由于现在只学了C语言所以就写这个C语言版的栈的基本操作

这里说一下 :网上和书上都有这种写法 int InitStack(SqStack &p)

&p是取地址  但是这种用法好像C并不支持 ,C++才支持,所以用

C语言写就需要使用指针

代码如下:

1 #include

2 #include

3 #define STACK_INIT_SIZE 100//储存空间初始分配量

4 #define STACKINCREMENT 10//存储空间分配增量

5 #define OK 1

6 #define ERROR 0

7 typedef int StackType; //栈元素类型

8

9 typedef struct{10 StackType *base; //在构造之前和销毁之后,base的值为NULL

11 StackType *top; //栈顶指针

12 int stacksize; //当前已分配的存储空间,以元素为单位

13 }SqStack; //顺序栈14

15 //栈的初始化

16 int InitStack(SqStack *p) {17

18

19 p->base = (StackType*)malloc(STACK_INIT_SIZE * sizeof(StackType));20 if (p->base == NULL) return ERROR; //内存分配失败

21 p->top = p->base; //栈顶与栈底相同表示一个空栈

22 p->stacksize =STACK_INIT_SIZE;23 returnOK;24

25 }26 //判断栈是否为空

27 int EmptyStack(SqStack *p) {28 //若为空栈 则返回OK,否则返回ERROR

29 if (p->top == p->base) returnOK;30 else returnERROR;31 }32 //顺序栈的压入

33 int Push(SqStack *p,StackType e) {34 //插入元素e为新的栈顶元素

35 if ((p->top - p->base)>= p->stacksize) //栈满,追加储存空间

36 {37 p->base = (StackType*)realloc(p->base, (p->stacksize + STACKINCREMENT) * sizeof(StackType));38 if (p->base == NULL) return ERROR;//储存空间分配失败

39 p->top = p->base + p->stacksize; //可能有人觉得这句有点多余(我当时也是这么想的 后面有解释)

40 p->stacksize +=STACKINCREMENT;41 }42 *(p->top) =e;43 (p->top)++;44 returnOK;45 }46 //顺序栈的弹出

47 int Pop(SqStack *p,StackType *e) {48 //若栈不空,则删除p的栈顶元素,用e返回其值

49 if (p->top == p->base) returnERROR;50 --(p->top);51 *e = *(p->top);52 returnOK;53

54

55 }56 //顺序栈的销毁

57 int DestroyStack(SqStack *p) {58 //释放栈底空间并置空

59 free(p->base);60 p->base =NULL;61 p->top =NULL;62 p->stacksize = 0;63

64 returnOK;65 }66 //将顺序栈置空 栈还是存在的,栈中的元素也存在,如果有栈中元素的地址任然能调用

67 int ClearStack(SqStack *p) {68 p->top= p->base;69 returnOK;70 }71 //返回顺序栈的元素个数

72 intStackLength(SqStack p) {73 //栈顶指针减去栈底指针等于长度,因为栈顶指针指向当前栈顶元素的下一个位置

74 return p.top - p.base;75 }76 //返回顺序栈的栈顶元素

77 int GetTop(SqStack *p, StackType *e) {78 //若栈不为空,则用e返回p的栈顶元素

79 if (p->top > p->base) {80 *e = *(p->top - 1); returnOK;81 }82 else returnERROR;83 }84 //从栈顶到栈底对每个元素调用某个函数

85 int StackTraverse(SqStack p,void (*pfun)(StackType)/*函数指针*/){86 //从栈底到栈顶依次对栈中的每个元素调用函数pfun()

87 while (p.top > p.base)88 pfun(*(p.base)++); //先调用后递增

89 printf("");90 returnOK;91 }92 //打印栈中元素

93 voidprint(StackType stack) {94 printf("%d", stack);95

96 }97 //测试栈的各种操作

98 intmain() {99 intn,i;100 StackType *e,a;101 SqStack *pstack,stack;102 pstack = &stack;103 e=(StackType*)malloc(sizeof(StackType)); //为指针e分配内存地址

104 InitStack(pstack); //初始化栈

105

106 if (EmptyStack(pstack) == 1) printf("-------栈为空-------");107 printf("请输入栈的元素个数:");108 scanf("%d", &n);109 for (i = 0; i < n; i++)110 {111 scanf("%d", &a);112 Push(pstack, a);113 }114 if (EmptyStack(pstack) == 0) printf("-------栈不为空-----");115

116 printf("栈的长度为:%d", StackLength(stack));117 printf("--------------------");118 printf("请输入一个入栈元素:");119 scanf("%d", &a);120 Push(pstack, a);121 printf("--------------------");122 printf("栈中的元素个数为:%d", StackLength(stack));123 printf("--------------------");124 GetTop(pstack, e);125 printf("栈顶元素为:%d", *e);126 printf("--------------------");127 printf("打印栈中的元素:");128 StackTraverse(stack, print);129 printf("---弹出栈顶元素---");130 Pop(pstack, e);131 printf("弹出的栈顶元素为:%d", *e);132 printf("--------------------");133 GetTop(pstack, e);134 printf("栈顶元素为:%d", *e);135 printf("--------------------");136 printf("打印栈中的元素:");137 StackTraverse(stack, print);138 printf("--------------------");139

140 printf("----------清空栈-------");141 if (ClearStack(pstack) == 0) printf("已清空栈");142

143 printf("----------销毁栈-------");144 if (DestroyStack(pstack) == 0) printf("已销毁栈");145 return 0;146

147 }

第39行  p->top = p->base + p->stacksize;这句有必要加上吗?  答案是肯定的。

这一个问题的关键在于 realloc 是怎么实现的,有两种情况:

如果有足够空间用于扩大mem_address指向的内存块,则分配额外内存,并返回mem_address。

这里说的是“扩大”,我们知道,realloc是从堆上分配内存的,当扩大一块内存空间时,

realloc()试图直接从堆上现存的数据后面的那些字节中获得附加的字节,如果能够满足,自然天下太平。

也就是说,如果原先的内存大小后面还有足够的空闲空间用来分配,加上原来的空间大小= newsize。

那么就ok。得到的是一块连续的内存。

如果原先的内存大小后面没有足够的空闲空间用来分配,那么从堆中另外找一块newsize大小的内存。

并把原来大小内存空间中的内容复制到newsize中。返回新的mem_address指针。(数据被移动了)。老块被放回堆上。

如果是第二种情况的话,s->top 就不是原来的 top 了     --百度百科

写这些代码的时候还是遇到了一些问题 在这里总结一下:

第一 对于指针的使用要慎重 因为它传递进函数会改变原始数据,所以对于不需要改变

指针指向的值的情况就不要使用指针。

第二 对于指针的使用  如下定义 int *e=NULL; *e=3;

看着好像没有问题  编译也没问题 但是运行程序就出错

为什么?  没有为指针e分配内存地址 所以引用肯定错误啊(我这个逗逼错误-_-)

正确的用法应该是 int *e=NULL;e=(int*)malloc(sizeof(int)); *e=3;

我之前都是 int *e,a; e=&a; e=3; 这种用法 所以......

c语言顺序栈完整程序,顺序栈的基本操作(C语言)相关推荐

  1. 黑马程序员 C语言数据结构与算法之线性表(链表/栈/队列/顺序表)

    C语言 链表基础知识清晰讲解(黑马) 讲的蛮好,就是音质不太好,有时听不清讲的啥! [黑马]数据结构与算法之线性表(链表/栈/队列/顺序表)[配套源码 嘛蛋,看错了,这是java的... 文章目录 链 ...

  2. c语言建立栈(顺序栈、双栈和链式栈)

    c语言建立栈 顺序存储 栈的顺序存储定义 初始化栈 入栈操作 出栈操作 其余操作 读取栈顶元素 栈中元素个数 栈是否为空 双栈 双栈的顺序存储结构定义 建立双栈 判断栈为空 进栈操作 出栈操作 链式栈 ...

  3. C语言实现了一个顺序栈(附完整源码)

    C语言实现了一个顺序栈 顺序栈 顺序栈结构示意图如下 C语言实现了一个顺序栈完整源码 顺序栈 用一段连续的存储空间来存储栈中的数据元素,比较常见的是用数组来实现顺序栈 顺序存储结构:1.元素所占的存储 ...

  4. c语言存储的逻辑顺序,栈是不是顺序储存的线性结构啊?

    栈是不是顺序储存的线性结构啊?以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 栈是不是顺序储存的线性结构啊? 呃~弄明白 ...

  5. c语言函数参数从右往左,C语言函数入参压栈顺序为什么是从右向左?

    看到有人提问到,在处理printf/cout时,压栈顺序是什么样的?大家都知道是从右往左,也就是说从右往左的计算,但是,这里的计算不等于输出. a++和++a的压栈的区别:在计算时,遇到a++会记录此 ...

  6. 数据结构:顺序栈基本操作(入栈和出栈)C语言详解(转载)by解学武

    本文为解学武教程的免费章节 什么是顺序栈 顺序栈,即用顺序表实现栈存储结构.通过前面的学习我们知道,使用栈存储结构操作数据元素必须遵守 "先进后出" 的原则,本节就 "如 ...

  7. 顺序栈基本操作(入栈和出栈)C语言详解

    #include <stdio.h> #include <stdlib.h> /*顺序栈基本操作(入栈和出栈)C语言详解栈的具体实现(1)顺序栈(2)链栈栈的应用(1)回退 ( ...

  8. 实现顺序栈的各种基本运算的算法C语言,实现顺序栈的各种基本运算的算法

    试编写一个算法,让两个顺序栈共用一个数组stack[N]试编写一个算法,让两个顺序栈共用一个数组stack[N],分别实现入栈\出栈操要2个栈公用一个存储空间看来栈顶指针只能从两端开始了(和队列有点像 ...

  9. c语言堆栈基本代码入栈出栈_顺序栈基本操作(入栈和出栈)C语言详解

    顺序,即用{1,2,3,4},存储状态如 图 1 顺序表存储 {1,2,3,4} 同样,使用栈存储结构存储 {1,2,3,4},其存储状态如图 2 所示: 图 2 栈结构存储 {1,2,3,4} 通过 ...

最新文章

  1. Android中Sharedpreferences牵涉到跨进程时不能实时读取的问题
  2. MySQL-索引优化篇(2)_使用索引扫描来优化排序
  3. linux efi不要boot目录,LINUX下EFIBOOTMGR的使用,删除UEFI主板多余启动项和添加启动项-Go语言中文社区...
  4. 【斩获7枚offer,入职阿里平台事业部】横扫阿里、美团、京东、 去哪儿之后,写下了这篇面经!
  5. 随机猜拳判断胜利(思路,逻辑正确不完美)if switch
  6. Editability on SAP Text
  7. 谈谈MySQL面试的45个常见问题
  8. codeforces gym-101736 Dessert First Strategy 最小割
  9. Android笔记-Activity相关+内存泄漏
  10. 基于微信小程序的用户列表点赞功能
  11. Java高级架构师(一)第05节:TortoiseGit的本地使用
  12. systemd.conf翻译
  13. 第8章 集成Log4J日志
  14. RHCSA-Day1 --- Linux介绍及环境搭建
  15. Linux下 安装白鹭(egret)引擎指南
  16. Tapdata 创始人唐建法:以秒级响应速度,为企业提供实时数据服务 | 阿里云云原生加速器特别报道
  17. 指令集创始人潘爱民博士荣获CSDN“2021年度IT领军人物”
  18. python之利用requests库爬取西刺代理,并检验IP的活性
  19. 阐述html语言的理解,阐述读书求学问的态度是以求学为快乐的句子是:(三重境界)             ,             。 ——青夏教育精英家教网——...
  20. mysql查询已知两列第三列,MySQL查询从两列中查找出现的次数?

热门文章

  1. 【深度相机系列一】iPhone X的原深感相机到底是个什么玩意?
  2. 【Java 19】反射 - 反射机制概述、获取Class实例、类的加载与ClassLoader的理解、创建运行时类的对象、获取运行时类的完整结构、调用运行时类的指定结构、动态代理
  3. GUI原理1 - 色彩王国
  4. :active vs :focus
  5. android 丢帧率测试,Android流畅度测试
  6. SSM酒店管理系统项目Day2
  7. 聚星Note06 - 角色维护(1)
  8. GET和POST测试(支持需要登录的接口调用:高级功能-填写cookie)
  9. 【报告分享】2021年中国汽车行业研究报告-360智慧商业(附下载)
  10. Dropbox再曝泄密危机 亚信安全建议企业用户部署安全的私有云存储