c语言 stack用法,C语言使用 void 指针实现Stack

数据结构基础课的教材使用C来实现数据结构,上学期看别的书用C++实现时还没什么感觉,一对比就发现C++的类和模板用起来比C方便多了。

在写四则运算计算器的时候,int写一遍,char还得写一遍感觉十分痛苦,百度了一下有没有别的解决办法,发现了下面这篇文章。

如何利用堆栈及逆波兰表达式进行数学四则运算:http://www.xuebuyuan.com/1602553.html

关键是在于理解 void 指针与一般指针的不同之处是它只保存数据的首地址,而不知道也不关心数据究竟有多少个字节。

因此利用 memcpy 可以无视数据类型进行赋值,这就让我们能够创建多种类型的Stack。

由于 memcpy 的参数是 void 指针,所以Push和Pop的都只接受地址作为参数,并且直接将改变应用于相应的内存单元,并不返回值。

此外,此处实现的Top指针也和一般的Stack定义不同,此处的Top指针总是指向下一个可用的内存单元。

仿照着写了一个Stack的实现如下:

1 //stack.h2 //This stack is implemented by void pointer, so it is GENERIC.3 //

4 //How the void pointer allows assignments of different data types:5 //first, a normal pointer is binded to a data type, so it knows the number of bytes of the6 //data it points to. second, it has an address, which is the start-address of the data.7 //so they can tell the compiler where to start and where to stop accessing the data.8 //

9 //but void pointer is binded to no data type. it only knows the starting-address.10 //so it can be forcely assigned to any pointers, thus allowing assignments of all data types.11 //so what we do is: when we create the stack, we MALLOC a block of free space, and we take a12 //integer, the typesize, which specifies the length of the data.13 //We use the function MEMCPY, which directly access the addresses,to push the data in the stack14 //and pop data out of the stack.15 //

16 //The difference from the definiton:17 //the stack pointer here is different from the definition.18 //when the stack is empty, Top == base.19 //when an element is pushed in, Top points to the address after the last byte of the element.20 //so the Top always points to the next available space.

21

22 #include

23 #include

24

25 structRecord26 {27 void *Top;28 void *base;29 intstacksize;30  size_ttypesize;31 };32

33 typedef struct Record *Stack;34

35 Stack CreateStack(intstacksize, size_t typesize);36 void Push(Stack S, void *data);37 void Pop(Stack S, void *data);38 intIsEmpty(Stack S);39 voidClear(Stack S);40 void Destroy(Stack S);

//stack.c

#include"stack.h"#includeStack CreateStack(intstacksize, size_t typesize)

{

Stack S= (Stack)malloc(sizeof(structRecord));

S->base = malloc(stacksize*typesize);if(!S->base)

{

printf("Out of space.\n");

exit(1);

}

S->Top = S->base;

S->stacksize =stacksize;

S->typesize =typesize;returnS;

}void Push( Stack S, void *data)

{if( (int)(S->Top - S->base) + S->typesize > S->stacksize )

{

printf("Out of space to Push.\n");

exit(1);

}

memcpy(S->Top, data, S->typesize);

S->Top = (void*)( (int)S->Top + S->typesize );

}//GNU defines the arithmetic of void* equals to char(which is defined as byte).//ANSI says we cannot do arithmetic on void* because we don‘t know the type.//so when we update the Top pointer, first regard it as an int, and convert it//back when we are finished.

void Pop( Stack S, void *data)

{if( S->Top == S->base)

{

printf("Error:Popping an empty stack.\n");

exit(1);

}

S->Top = (void*)( (int)S->Top - S->typesize);

memcpy(data, S->Top, S->typesize);

}voidClear(Stack S)

{

S->Top = S->base;

}intIsEmpty(Stack S)

{return S->Top == S->base;

}voidDestroy(Stack S)

{

free(S->base);

}

原文:http://www.cnblogs.com/jeffo/p/stack-using-void-pointer.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值