栈是一种用得比较多的数据结构,用处很广。但很多时候,栈中的元素是不一样的。那如何写一个通用的栈呢。在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;
else
return 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;
else
return 0;
}
/* 判断栈是否为空 */
int is_empty(stack *s)
{
if (s->top - s->base == 0)
return 1;
else
return 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')这种,因为取地址编译不通过。