本例主要是实现一个顺序栈;其它的啥也不说;直接上代码:
/*
或许这就是指针的魅力;也是指针折磨人的地方。指针可以直接对内存进行操作,非常强大;它操作的对象是地址;是计算机最本质的东西;你在操作的时候是比较爽了;但是当你在程序中“不小心”改变了指针变量的值;当你再次访问时;就会出现一些莫名其妙的错误(通常是访问了不该访问的内存,因为指针的内容变了;但是程序的逻辑是没有任何错误的;你就会变得特别崩溃;本例具体的错误如下所示);*/
#include<stdio.h>
#include<stdlib.h>#define STACK_INIT_SIZE 10
#define STACK_INCREASE 2typedef struct STACK
{ int *pBase; int *pTop; int size;} Stack; void InitStack(Stack *);void DestroyStack(Stack *);void ClearStack(Stack *);int Empty(Stack *);int LengthStack(Stack *);int GetTop(Stack *, int *);void Push(Stack *, int);int Pop(Stack *, int *);void TraverseStack(Stack *); int main(void){ int i; int e, e0; Stack S;InitStack(&S);
for (i=0; i<10; i++)
{ Push(&S, i); } /*因为在程序中有了这句;所以我在进行弹出操作时怎样也不对;打印出的e值总是垃圾数据;折腾了许久 才知道:在遍历程序中我改变了栈底指针的值;而在弹出操作中我又使用到了栈底指针;所以才会出现错误 因为是指针;在程序中某一处改变了它的值;那么在再次访问时就会影响;所以本程序写的并不好*/ TraverseStack(&S); for (i=0; i<6; i++) { if (Pop(&S, &e) == 1) { printf("pop success; the data is %d \n", e); } else printf("pop failed !\n"); } if (GetTop(&S, &e0) == 1) { printf("the top element is %d \n", e0); } else printf(" may be stack is empty;may be code exit error.\n");return 0;
} /*和线性结构一样,这样便构造了一个线性表;也就是一个结构体,这个结构体保存了这个线性表的基本信息*/void InitStack(Stack * S){ S->pBase = (int *)malloc(sizeof(int)*STACK_INIT_SIZE); if (S->pBase == NULL) { printf("alloc memery is failed! \n"); exit(-1); } S->pTop = S->pBase; S->size = STACK_INIT_SIZE;}void DestroyStack(Stack * S)
{ free(S->pBase); S->pBase = NULL; S->pTop = NULL; S->size = 0;}void ClearStack(Stack *S)
{ S->pTop = S->pBase;}int Empty(Stack *S)
{ if (S->pBase == S->pTop) return 1; else return 0;}int LengthStack(Stack * S)
{ return S->pTop - S->pBase;}/*该段代码不好;因为改变了栈顶指针的值;如果再次被调用;则会出现错误*/int GetTop(Stack *S, int *element){ int *p = S->pTop;if (p > S->pBase)
{ *element = *(p - 1); return 1; } else return 0;}void Push(Stack *S, int element)
{ if (S->pTop - S->pBase == S->size)//当栈满是一种情况 { S->pBase = (int *)realloc(S->pBase, (STACK_INIT_SIZE + STACK_INCREASE) * sizeof(int)); if (S->pBase == NULL) { printf("alloc memery is failed! \n"); exit(-1); } else { S->pTop = S->pBase + S->size; S->size += STACK_INCREASE; } } else //栈不满的情况 { *(S->pTop) = element; S->pTop ++ ; } }int Pop(Stack *S, int *element)
{ if (S->pBase == S->pTop) return 0; -- S->pTop; *element = *(S->pTop);return 1;
}/*弹出元素总是不成功,是不是因为在调用TraverseStack()函数时,将栈底指针改变了;所以才会造成各种错误*/
void TraverseStack(Stack *S){ int *p = NULL;//由错误提醒我们:在操作时,不要直接对全局变量操作;给它一个初值再进行操作;可能效好 p = S->pBase;while (p < S->pTop)
{ printf("%d ", *p); p++; } printf("\n");}