有趣生活

当前位置:首页>科技>什么是抽象数据类型定义举例抽象数据类型ADT与接口

什么是抽象数据类型定义举例抽象数据类型ADT与接口

发布时间:2026-07-25阅读(1)

导读对于计算机科学来说,抽象(abstractions)是一个很重要的思维概念,与之相关的概念还有模块、分层等,如对一个复杂系统的模块化和层层抽象。如下图所示,....

对于计算机科学来说,抽象(abstractions)是一个很重要的思维概念,与之相关的概念还有模块、分层等,如对一个复杂系统的模块化和层层抽象。

如下图所示,计算机体系的分层结构,上层便是下层的抽象。

一般来说,所有高级编程语言也都提供抽象(abstractions)机制。某一功能或某一问题解决方案具体过程的描述,可以抽象为函数(算法也可以用函数来描述)。

对某类实体,可以抽象出共同的关键性的特性描述(数据)和行为(或功能,用函数或成员函数描述),在编程语言中称为抽象数据类型(ADT,Abstract Data Type)。

C和C 都可以实现一种抽象数据类型。

在C中,ADT的数据可以抽象为结构体(struct),如描述栈的struct:struct Statck stack。相应的,ADT的行为可以抽象为一个函数集,这些函数是对数据stack的处理或操作,这些函数通常以stack或其指针做为函数参数。

在C 中,ADT可以用类(class)来描述,ADT的数据及其对该数据的处理(成员函数)都被封装到一个类中。

通常,一种抽象数据类型可以用一个模块(mudole)来描述。在C和C 中,文件也是一种实现模块的方式之一。可通过头文件(.h)和源文件(.c或.cpp)实现模块化,实现接口(interface)与实现(implementation)的分离和封装。

C的头文件:可以包含结构体 函数原型声明;

C的源文件:可以包含各个函数实现;

C的头文件:可以包含类定义;

C的源文件:可以包含类的各个成员的函数实现;

更进一步,实现文件可以封装为库(函数库或类库,lib或dll)。

对于封装后的ADT,ADT的使用者(client)无须使用时无须关注ADT的实现文件或库文件(.lib或.dll),只需引入和对照接口文件(头文件)即可使用ADT。同时,ADT实现者(implementor)随时可以修改实现文件(不修改接口文件),不会影响client使用ADT的代码,这也就是所谓的实现隐藏,这也是封装的一个重要特征。

下面以实现一个链栈为例为说明C和C 在抽象数据类型方面的异同:

1 C栈实现抽象数据类型(ADT)

1.1 头文件(充当接口)

// Stack.h for interface#ifndef STACK_H#define STACK_Htypedef struct Link { // 链表节点 void* data; Link* next;}Link;typedef struct tagStack { // 链栈 Link* top; int size;}*Stack;void initLink(Link* link, void* dat, Link* nxt);void init(Stack stack);void push(Stack stack,void* dat);void* peek(Stack stack);void* pop(Stack stack);#endif

1.2 实现文件

// Stack.cpp// Includes definitions of member functions#include "Stack.h"#include <stdio.h>#include <stdlib.h>void initLink(Link* link, void* dat, Link* nxt){ link->data = dat; link->next = nxt;}void init(Stack stack) { stack->top = NULL; stack->size = 0;}void push(Stack stack,void* dat) { Link* newLink = (Link*)malloc(sizeof(Link)); initLink(newLink,dat,stack->top); stack->top = newLink; stack->size ;}void* peek(Stack stack) { if(stack->top==NULL) { printf("Stack empty!\n"); exit(0); } return stack->top->data;}void* pop(Stack stack) { if(stack->top == NULL) return NULL; void* result = stack->top->data; Link* oldtop = stack->top; stack->top = stack->top->next; free(oldtop); stack->size--; printf("%d\t",stack->size); return result;}

1.3 测试文件(充当client)

// StackTest.cpp// Test of nested linked list#include "Stack.h"#include <stdio.h>#include <stdlib.h>int main() { struct tagStack nums; init(&nums); for(int i=1; i<11; i ) { void *ptr = malloc(sizeof(double)); *(double*)ptr = i*0.5; push(&nums,ptr); } // Pop the lines from the Stack and print them: double * ptr; while(nums.top != NULL) { ptr = (double*)pop(&nums); printf("%lf\n",*ptr); free(ptr); } while(1); // for test return 0;}

2 C 实现栈抽象数据类型

2.1 头文件(充当接口)

// Stack.h for interface#ifndef STACK_H#define STACK_Hclass Stack { struct Link { // void* data; Link* next; Link(void* dat, Link* nxt); }* top;public: Stack(); void push(void* dat); void* peek(); void* pop();};#endif

2.2 实现文件

// Stack.cpp// Includes definitions of member functions#include "Stack.h"#include <iostream>Stack::Link::Link(void* dat, Link* nxt) { data = dat; next = nxt;}Stack::Stack() { top = 0; }void Stack::push(void* dat) { Link* newLink = new Link(dat, top); top = newLink;}void* Stack::peek() { if(top==0) { std::cout<<"Stack empty!\n"; exit(0); } return top->data;}void* Stack::pop() { if(top == 0) return 0; void* result = top->data; Link* oldtop = top; top = top->next; delete oldtop; return result;}

2.3 测试文件(充当client)

// StackTest.cpp// Test of nested linked list#include "Stack.h"#include<fstream>#include<iostream>#include<string>using namespace std;int main() { Stack nums; for(int i=1; i<11; i ) nums.push(new int(i)); // Pop the lines from the Stack and print them: int * ptr; while((ptr = (int*)nums.pop()) != NULL) { cout << *ptr << endl; delete ptr; } while(1); // for test return 0;}

-End-

Copyright © 2024 有趣生活 All Rights Reserve吉ICP备19000289号-5 TXT地图HTML地图XML地图