我们在做课程作业的时候,每次都会用到各种各样的数据结构,用得最多的当属栈,比如我们在做编译原理的时候,总是会遇到很多识别栈啊、输入栈啊什么的,之前每次做的时候总是需要新构造一种栈来满足不同的数据结构,早就开始想要自己构造一个万能的栈。
仔细想了一下,实际上用户层的程序若要使用一个栈,那么用户层的代码必定知道在栈中的元素应该是什么数据结构,c语言好像不能像c++一样把数据的类型当做一个参数在函数之间传递(可能可以,但是我学艺不精不知道),一直在想怎么解决这个问题,后来突然灵光一闪,感觉栈里放的元素好像并不需要知道他具体是什么类型的,相反我们只要知道它的size就行了,如果我们要进行数据内部的操作的话,可以把它读出之后强制转化成我们所知道的数据结构再进行操作,而这与栈本身的功能没有关系。
然后思路就很明了了,也没什么技术难度,只是涉及到一些控制真的操作而已。
请看代码:
stack.h:
//author liangdong
//2013/6/1
#include<stdlib.h>
typedef struct Stack
{
void* stack;
int Length;
int Count;
int StructLength;
void* head;
void* tail;
}Stack;
void createStack(Stack* Stac,int Length,int SizeOfType);
int pushStack(void* a,struct Stack* ST);
void* popStack(struct Stack* st);
int freeStack(struct Stack* st);
stack.c
#include"stack.h"
//this function Init a stack
static void InitStack(Stack* stac,int size,int length)
{
stac->stack=(void*)malloc(size*length);
stac->Length=length;
stac->Count=0;
stac->StructLength=size;
stac->head=stac->stack;
stac->tail=stac->stack;
}
//this is the interface for user
void createStack(Stack* Stac,int Length,int SizeOfType)
{
InitStack(Stac,SizeOfType,Length);
}
//this function push the stack
static int push(void* a,struct Stack* st)
{
st->head+=st->StructLength;
st->head=a;
st->Count++;
if(st->Count>st->Length)
{
return 0;
}
return 1;
}
//this is the interface for user
int pushStack(void* a,struct Stack* ST)
{
return push(a,ST);
}
//this functione pop the stack head
static void* pop(struct Stack* st)
{
st->Count--;
st->head-=st->StructLength;
if(st->Count==0)
{
return (st->head)+(st->StructLength);
}
return NULL;
}
//interface
void* popStack(struct Stack* st)
{
return pop(st);
}
//this use to destory the stacke
static int destory(struct Stack* st)
{
free(st->stack);
st->stack=NULL;
return 1;
}
//interface
int freeStack(struct Stack* st)
{
return destory(st);
}
测试代码:
#include<stdio.h>
#include"stack.h"
typedef struct
{
int a;
int b;
}testItem;
int main()
{
Stack st;
createStack(&st,10,sizeof(testItem));
testItem ti;
ti.a=0;
ti.b=1;
pushStack(&ti,&st);
testItem *till;
if((till=popStack(&st))==NULL)
{
printf("stack empty!\n");
}
printf("%d\n",till->a);
printf("%d\n",till->b);
freeStack(&st);
return 0;
}
当然,功能函数里面的栈访问安全性还存在一定问题,本人懒惰,一般做事虎头蛇尾,加之这几天考试,实在不想动代码,朋友们有兴趣帮忙改改吧。