通用栈

来源:互联网 发布:js设置超链接不可点击 编辑:程序博客网 时间:2024/05/03 13:45

栈是一种用得比较多的数据结构,用处很广。但很多时候,栈中的元素是不一样的。那如何写一个通用的栈呢。在C++中有模板,那如何用C实现通用的栈呢。

在C语言中,不同的数据类型,占用的字节数不一样。参考qsort对不同数据类型的排序方法,可以得知,使用一个指针,以及此类型的大小即可。

具体的请参考以下代码实现。

/*实现通用的栈结构 */#include <stdio.h>typedef struct{char *base, *top;int item_size; //栈中每个元素所占的字节数。int item_num;}stack;/* 创建含有item_num个元素,每个元素占有item_size个字节数的栈 * 返回栈的指针 * */stack * create_stack(stack *s, int item_size, int item_num);/* 释放栈空间 */void free_stack(stack *s);/* 判断栈是否已满 */int is_full(stack *s);/* 判断栈是否为空 */int is_empty(stack *s);/* push item 所指向的元素进栈*/void push(stack *s, const void *item);void pop(stack *s, void *item);//方便操作的宏定义#define PUSH(s,e) do {\push(&s, (char*)&e);\}while(0);#define POP(s,e) do{\pop(&s, (char*)&e);\}while(0);int main(){stack s;create_stack(&s, sizeof(char), 10);char c;c = 'a';PUSH(s, c);c = 'b';PUSH(s, c);c = 'c';PUSH(s, c);c = 0;POP(s, c);printf("%c\n", c);POP(s, c);printf("%c\n", c);//pop(&s, c);POP(s, c);printf("%c\n", c);free(&s);return 0;}/* 创建含有ele_num个元素,每个元素占有item_size个字节数的栈 * 返回栈的指针 * */stack * create_stack(stack *s, int item_size, int item_num){if (s == NULL) return NULL;item_num = item_num>0 ? item_num : 1;s->base = s->top = (char*)malloc(item_size * item_num);s->item_num = item_num;s->item_size = item_size;if (s->base==NULL)return NULL;elsereturn s;}/* 释放栈空间 */void free_stack(stack *s){free(s->base);s->base = s->top = NULL;}/* 判断栈是否已满 */int is_full(stack *s){if ((s->top - s->base)/s->item_size >= s->item_num)return 1;elsereturn 0;}/* 判断栈是否为空 */int is_empty(stack *s){if (s->top - s->base == 0)return 1;elsereturn 0;}void push(stack *s, const void *item){if (is_full(s))return;void *p = &item;memcpy(s->top, item, s->item_size);s->top += s->item_size;} void pop(stack *s, void *item){if (is_empty(s))return;s->top -= s->item_size;memcpy(item, s->top, s->item_size);} 
为了更符合使用习惯,将pop和push函数经过宏封闭。


缺点:push时,不能是常量,如 push(s, 'a')这种,因为取地址编译不通过。