人生总是有很多意外,弄着弄着C#去让我去搞C语言,这不是一种退化么,不过经过一段时间的学习,发现C语言还真是超级强大,主要的问题就是它太简单了,简单到天马行空,怎么弄都行,但是只有一种方法是对的,出现的问题千奇百怪,编辑器回归记事本,debug变成屏幕打印……
C#中的object是最终极的父类,很多设计上的内容,都是利用这个东东实现了ADT,但是对于面向过程的C语言来说,能否实现类似的功能呢?
C语言中的无类型指针void*,就有着这样的良好特性,它不具备类型,也可以把它理解为一块纯粹的内存空间,如果要对它进行操作,就要强制给它一个类型,类型转换的对错它是检查不出来,所以用这哥们也是有一点危险性的。
接下来就是写一个C语言的栈的例子,功能上的要求就是这套接口要与最终实现分离,意思是栈里装什么东西,这是用户的事情。
可以创建,pop,push,删除,和检测是否为空。
头文件的定义:
#ifndef STACK_INCLUDED #define STACK_INCLUDED #define T Stack_T typedef struct T *T; extern T Stack_new (void); extern int Stack_empty (T stk); extern void Stack_push (T stk,void *x); extern void *Stack_pop (T stk); extern void Stack_free (T *stk); #undef T #endif?
实现:
#include <stddef.h> #include <stdlib.h> #include "stack.h" #define T Stack_T struct T{ int count; struct elem{ void *x; struct elem *link; } *head; }; T Stack_new(void) { T stk; stk=(T)malloc(sizeof(T)); stk->count=0; stk->head=NULL; return stk; }
?其他方法的实现过程也是类似的,其间的数据传递都是靠无类型指针,这个过程和C#里面使用泛型几乎是一样的。
int Stack_empty(T stk) { return stk->count==0; } void Stack_push(T stk,void *x) { struct elem *t; t=(struct elem *)malloc(sizeof(struct elem)); t->x=x; t->link=stk->head; stk->head=t; stk->count++; } void *Stack_pop(T stk) { void *x; struct elem *t; if(stk->count > 0) { t=stk->head; stk->head=t->link; stk->count --; x=t->x; free(t); return x; } else return NULL; }
?还剩下一个函数,有兴趣的同学可以自己写写看,用管了托管代码的,别忘了释放内存。