头文件:

#ifndef STACK_H
#define STACK_H#define STACK_INC_SIZE   5   //栈每次的增长大小
#define STACK_DEBUG 0X0010
#define STACK_INFO 0X0001
#define STACK_MSG(level, format, argc...) do{\if(stack_debug_level & level) \printf("["#level"]"format, ##argc);    \else   \;  \}while(0)struct data{void *value;int size;
};typedef struct stack{int top; struct data *data;struct stack *next;int used;int (*push)(struct stack* stack, void *data, int size);void* (*pop)(struct stack* stack);void (*destory)(struct stack** stack);
}t_stack;t_stack *init_stack(void);#endif

c文件

/*实现一个动态增长的栈思路:用多个栈组成链表leon2016-1-3 22:30:19
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "stack.h"static int stack_debug_level = 0; //STACK_DEBUG | STACK_INFO;/*返回栈内数据的指针!*/
static void* pop(struct stack* stack)
{t_stack *s = stack;if(!s){return NULL;}while(s->next && s->next->used){s = s->next;}if(s->top == 0){STACK_MSG(STACK_INFO, "The stack is enpty\n");return NULL;}/*这是栈里的最后一个元素,标记栈为未使用*/if(s->top == 1){s->used = 0;}s->top--;STACK_MSG(STACK_DEBUG, "stack pop success, the value addr %p\n", s->data[s->top].value);return s->data[s->top].value;
}static int push(struct stack* stack, void *data, int size)
{t_stack *inserted_stack;if(!stack){return -1;}/*找到最后一个可以使用的栈*/while(stack->next && stack->used){stack = stack->next;}if(stack->top < STACK_INC_SIZE){inserted_stack = stack;}else /*溢出*/{/*没有可以使用的栈,则初始化新栈*/if(!stack->next){inserted_stack = init_stack();if(!inserted_stack){return -1;}stack->next = inserted_stack;}   /*used = 0, 以前有开辟新栈,只是出栈使其成为了空栈*/else{inserted_stack = stack->next;}STACK_MSG(STACK_INFO, "increce stack size\n");    }inserted_stack->data[inserted_stack->top].value = malloc(size);if(!inserted_stack->data[inserted_stack->top].value){printf("The memery is not enough!\n");return -1;}memcpy(inserted_stack->data[inserted_stack->top].value, data, size);inserted_stack->data[inserted_stack->top].size = size;inserted_stack->top++;inserted_stack->used = 1;STACK_MSG(STACK_DEBUG, "stack push success, top = %d\n", inserted_stack->top);return 0;
}static void destory(struct stack** stack)
{t_stack *s = *stack;t_stack *del = s;int i;if(!s){return;}while(s){for(i = 0; i < STACK_INC_SIZE; i++){if(s->data[i].value)free(s->data[i].value);}free(s->data);del = s;s = s->next;free(del);}*stack = NULL;STACK_MSG(STACK_INFO, "stack destory success\n");return;
}/*初始化一个栈*/
t_stack *init_stack(void)
{t_stack *s = (t_stack *)malloc(sizeof(t_stack));if(!s){printf("The memery is not enough!\n");return NULL;}memset(s, 0x0, sizeof(t_stack));s->data = malloc(sizeof(struct data) * STACK_INC_SIZE);if(!s->data){printf("The memery is not enough!\n");return NULL;}memset(s->data, 0x0, sizeof(struct data) * STACK_INC_SIZE);s->pop = &pop;s->push = &push;s->destory = &destory;STACK_MSG(STACK_INFO, "stack init success\n");return s;
}

最开始我用 s->data[s->top]->value的方式取value编译报错,一开始想不明白,因为data定义为指针的,就想着应该用'->'而不是'.'。后来明白了,data[]这个中括号,会取值,因此后面该接‘.’。如果执意要用‘->’,需要这要写:(s->data + s->top)->value.

测试代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "stack.h"int main(int argc, char *argv[])
{t_stack *s = init_stack();if(!s)return -1;int i = 0;for(i = 1; i < argc; i++){s->push(s, (void *)argv[i], strlen(argv[i]) + 1);}char *p = (char *)(s->pop(s));while(p){printf("%s\n", p);p = (char *)(s->pop(s));}s->destory(&s);return 0;
}

makefile

TARGET = a.outOBJ = main.o stack.oall: $(OBJ)gcc -o $(TARGET) $(OBJ)./$(TARGET) 0 1 2 3 4 5 6 7%.o: %.c gcc -Wall -Werror -g -MMD -c $< clean:-rm $(OBJ) $(OBJ:%.o=%.d) a.out-include $(OBJ:%.o=%.d).PHONY: all clean

一个动态增长的栈实现相关推荐

  1. java动态扩展_java栈内存动态扩展要怎么理解?要如何实现?

    小伙伴们知道如何在java栈中内存动态扩展吗?这是虚拟机中的一个概念,下面让我们一起来看看该如何实现吧. 一.内存概念 在java中,我们一般会简单把java内存区域划为两种:堆内存与栈内存.其实这种 ...

  2. 用 python 做一个动态可视化交互大屏

    你可能经常会在公司前台.展会.路演时看到可视化数据的交互大屏.今天我们就来用 python 做一个动态可视化的交互大屏图. 一.项目背景 随着科技的飞速发展,数据呈现爆发式的增长,任何人都摆脱不了与数 ...

  3. golang切片slice详解:介绍、内存分析、定义、遍历、切片可以继续切片、切片可以动态增长、切片的拷贝及底层原理

    切片的引入 [1]切片(slice)是golang中一种特有的数据类型 [2]数组有特定的用处,但是却有一些呆板(数组长度固定不可变),所以在 Go 语言的代码里并不是特别常见.相对的切片却是随处可见 ...

  4. 手撸一个动态数据源的Starter 完整编写一个Starter及融合项目的过程 保姆级教程

    手撸一个动态数据源的Starter! 文章目录 手撸一个动态数据源的Starter! 前言 一.准备工作 1,演示 2,项目目录结构 3,POM文件 二.思路 三.编写代码 1,定义核心注解 Ds 2 ...

  5. 动态区域(栈、堆)、静态存储区(数据段和程序段)

    动态区域(栈.堆).静态存储区(数据段和程序段) 内容收集比较混乱,仅供参考 版本一:      堆 1 类成员变量存放在堆区,所有类的实例和数组都是在堆上分配内存的,堆内存由存活和死亡的对象,空闲碎 ...

  6. android碎片调用动态碎片,Android Training - 使用碎片创建一个动态UI

    为了能够在Android中创建动态和多窗口的用户界面,你需要封装UI组件和activity行为在不同的模块中,以便你可以在不同的activity间切换.你可以使用Fragment类创建这些模块,类似于 ...

  7. 每天一道LeetCode-----实现一个栈,提供一个接口用于返回栈中最小值

    Min Stack 原题链接Min Stack 实现一个栈,除了基本功能外需要提供一个接口用于返回栈中元素的最小值 基本功能使用std::stack就够了,如果每次需要最小值时都遍历栈中元素的话会很麻 ...

  8. sqlserver如何定义一个静态变量_[Bazel]自定义规则实现将多个静态库合并为一个动态库或静态库...

    1 前言 2 自定义规则实现 2.1 规则功能 2.2 实现规则的理论基础 2.3 规则代码实现 3 总结 4 参考资料 1 前言 为了实现如标题所述的将多个静态库合并为一个动态库,内置的 Bazel ...

  9. 设单链表中存放n个字符,试设计一个算法,使用栈推断该字符串是否中心对称...

    版权声明:本文为博主原创文章.未经博主同意不得转载. vasttian https://blog.csdn.net/u012860063/article/details/28281631 转载请注明出 ...

最新文章

  1. Solidity基础入门知识(十)函数的访问权限和可见性
  2. #define list_entry(ptr, type, member) \   container_of(ptr, type, member)
  3. php 的ob start,php ob_start()函数详解
  4. 你应该知道的缓存进化史
  5. TEG六周年 | 同心筑梦 共赢未来
  6. python 列表自定义排序_自定义排序的Python列表
  7. 多媒体领域顶会,ACM MM 2020 会议论文下载
  8. 1132: 零起点学算法39——多组测试数据(a+b)
  9. IDL代码实现湖泊水体范围遥感提取
  10. C#自动识别文件编码
  11. 计算机专业的具体能力和素质要求,浅谈中职计算机专业学生职业素养的要求
  12. 素数c语言,C语言素数怎么表示
  13. GD32Pack包下载地址
  14. 阿里巴巴Java面试题、笔试题(含答案)
  15. Linux 嗅探 网络扫描 攻击防御神器 NMAP
  16. javascript-cropper插件翻译笔记
  17. 科技护肤品,买还是不买
  18. 美国博士后J1签证北京面签经过
  19. 入门激光雷达点云的3D目标检测
  20. 使用 IntraWeb (22) - 基本控件之 TIWCalendar

热门文章

  1. 1.3_bubble_sort_冒泡排序
  2. python最后输出两位小数_人生苦短,我用python!
  3. 启动zookeeper_架构设计 | 分布式系统调度,Zookeeper集群化管理
  4. CentOS中nginx负载均衡和反向代理的搭建
  5. P1601高精度加法
  6. 1、Keepalived及VRRP原理介绍
  7. 步步为营-93-MVC+EF简单实例
  8. hiho_100_八数码
  9. 菜鸟学习Spring——初识Spring
  10. 杭电OJ 敌兵布阵 树状数组