关于抽象数据类型的问题
今天看《C语言程序设计现代方法》中的大型程序设计,有很多小问题,请教各位高手
问题1.上面说
- C/C++ code
struct node{ int data; struct node *next;};struct stack_type{ struct node *top;};不要放在头文件里,这样用户就知道了具体是怎样实现的,不好。但是为什么要定义两个结构体呢?
书上是这样说的:
乍一看,这个结构似乎有点冗余:我们可以简单的把Stack定义为struct node * 同时让Stack的值为指向链表首节点的指针。但是,我们仍然需要这个stack_type结构,这样可以使栈的接口保持不变。(如果不这样做,任何一个对栈进行修改的函数都需要Stack * 类型的参数而不是Stack参数)。此外,如果将来我们想存储更多的信息,stack_type结构的存在可以简化对实现的修改。例如,如果我们以后想给stack_type结构增加栈数据项的计数器,可以很容易的为stack_type结构增加栈数据项的计数器,可以很容易的为stack_type增加一个成员来存储该信息。
仅仅是使接口不变么?应该还有深意吧,但是我不太了解。
问题2.弱智多了的一个问题:怎样在VC下实现多文件编译啊,我新建了一个空的控制台程序,把头文件和源文件都添加进去,这个时候是不是应该对单个文件分别编译呢?linux下可以gcc,但是在VC下呢?
还望高手不吝赐教。
stackADT.h
- C/C++ code
#include<stdio.h>#ifdef STACKADT_H#define STACKADT_Htypedef struct stack_type *Stack;Stack creat(void);void destroy(Stack s);void make_empty(Stack s);bool is_empty(Stack s);bool is_full(Stack s);void push(Stack s,int i);int pop(Stack s);#endif
stackADT.c
- C/C++ code
#include<stdio.h>#include<stdlib.h>#include"stackADT.h"struct node{ int data; struct node *next;};struct stack_type{ struct node *top;};static void terminate(const char *message){ printf("%s\n",message); exit(EXIT_FAILURE);}Stack create(void){ Stack s = malloc(sizeof(struct stack_type)); if(s == NULL) terminate("Error ... "); s -> top = NULL; retutn s; }void destroy(Stack s){ make_empty(s); free(s);}void make_empty(Stack s){ while(!is_empty(s)) pop(s);}int is_empty(Stack s){ return s -> top == NULL;}int is_full(Stack s){ return false;}void push(Stack s,int i){ struct node * new_node = malloc(sizeof(struct node)); if(new_node == NULL) terminate("Error ..."); new_node -> data = i; new_node -> next = s -> top; s -> top = new_node;}int pop(Stack s){ struct node * old_top; int i; if(is_empty(s)) terminate("Error ..."); old_top = s -> top; i = old_top -> data; s -> top = old_top -> next; free(old_top); return i;}stackclient.c
- C/C++ code
#include<stdio.h>#include"stackADT.h"int main(){ Stack s1,s2; int n; s1 = create(); s2 = create(); push(s1,1); push(s1,2); n = pop(s1); printf("Popped %d from s1\n,n"); push(s2,n); n = pop(s1); printf("Popped %d from s1\n,n"); push(s2,n); destroy(s1); while(! is_empty(s2)) printf("Popped %d from s2\n",pop(s2)); push(s2,3); make_empty(s2); if(is_empty(s2)) printf("s2 si empty\n"); else printf("s2 is not empty\n"); destroy(s2); return 0;}[解决办法]
问题1:
书上已经说得很清楚了,不仅是接口的问题。如果定义的栈多了个结构成员,就只需要修改代码。而不需要重新定义了。
问题2:
点编译按钮
[解决办法]
node的结构体不应频繁改变
[解决办法]
对一个对象在不同的层次上的抽象,
------解决方案--------------------
这样的话包含第二个结构体的源文件在第一个结构体发生变化时就不需要重新编译了。
只需要重新编译第一个结构体的源文件和第二个结构体的源文件,主动变化发生在第一个结构体源文件,被动变化发生在第二个结构体源文件,其他文件都不受影响。