C语言实现可复用栈
一、思考
最开始写的栈,通过宏来改变元素数据类型,在同一程序中只能用于一种数据类型,想要用于多种数据类型则要复制代码并改名。那么,有没有方法不复制代码就可以用于多种数据类型?
二、基本思路
在我的经验中,栈内的数据不参与运算,对元素的操作只有两种——流入和流出栈。也就是说,数据类型不重要,只要做到正确流入流出即可。(void*)
三、栈的源码
共2个文件,x_sq_stack.h、x_sq_stack.c。莫纠结前缀x,与代码无任何关系。
/*************************************************************
* x_sq_stack.h
*
* 固定大小的栈,顺序存储
* 把需要的数据类型重命名为s_elemtype即可
*
* **********************************************************/ #ifndef X_SQ_STACK_H
#define X_SQ_STACK_H #define OK 0 //pop()、push()函数成功返回
#define TRUE 1 //isnull()、isfull()
#define FALSE 0 //isnull()、isfull()
#define ERR_SQ_STACK_FULL 2 //栈满时push()函数返回
#define ERR_SQ_STACK_NULL 3 //栈空时pop()函数返回 typedef struct sq_stack{
void *base; //栈空间地址
int t_size; //元素大小(字节数)
int size; //栈大小
int top; //栈顶索引
}sq_stack; /***********************************************************
*
* 创建和销毁栈
*
* 参数:
* size 栈大小
* t_size 元素大小
*
* 返回:
* create_..() 不成功返回NULL
*
* ********************************************************/
struct sq_stack * create_sq_stack(int size, int t_size);
void free_sq_stack(struct sq_stack *s); /**********************************************************
*
* 入栈和出栈
* 成功都返回OK,不成功分别返回ERR_SQ_STACK_FULL、ERR_SQ_STACK_NULL
*
* ********************************************************/
int push_sq_stack(struct sq_stack *s, const void *data);
int pop_sq_stack(struct sq_stack *s, void *data); /**********************************************************
*
* 判断是否是满栈或空栈
* 成立返回TRUE,不成立返回FALSE
*
* ********************************************************/
int isfull_sq_stack(const struct sq_stack *s);
int isnull_sq_stack(const struct sq_stack *s); #endif /*X_SQ_STACK_H*/
/* x_sq_stack.c */ #include "x_sq_stack.h"
#include <string.h>
#include <stdlib.h> struct sq_stack * create_sq_stack(int size, int t_size)
{
struct sq_stack *s;
int mem_size = sizeof(struct sq_stack) + size*t_size;
if(!(s=(struct sq_stack *)malloc(mem_size))){
return NULL;
}
s->base = (void*)(s+);
s->size = size;
s->t_size = t_size;
s->top = -;
return s;
} void free_sq_stack(struct sq_stack *s)
{
free(s);
} int push_sq_stack(struct sq_stack *s, const void *data)
{
if(s->top < s->size-){
s->top ++;
memcpy(s->base + s->top * s->t_size, data, s->t_size);
return OK;
}else{
return ERR_SQ_STACK_FULL;
}
} int pop_sq_stack(struct sq_stack *s, void *data)
{
if(s->top >= ){
memcpy(data, s->base + s->top * s->t_size, s->t_size);
s->top --;
return OK;
}else{
return ERR_SQ_STACK_NULL;
}
} int isfull_sq_stack(const struct sq_stack *s)
{
if(s->top >= s->size-) return TRUE;
else return FALSE;
} int isnull_sq_stack(const struct sq_stack *s)
{
if(s->top < ) return TRUE;
else return FALSE;
}
四、测试
/* main.c */ #include "x_sq_stack.h"
#include <stdio.h> #define TYPE_1 long
#define TYPE_2 double int main(int argc, char *argv[])
{
sq_stack *s1,*s2; s1=create_sq_stack(,sizeof(TYPE_1));
s2=create_sq_stack(,sizeof(TYPE_2));
if(!s1 || !s2){
printf("内存分配失败!\n");
return ;
} double temp;
for(int i=; i<; i++){
if(push_sq_stack(s1,&i) == ERR_SQ_STACK_FULL){
printf("s1 栈已满!\n");
}
temp = i/2.1;
if(push_sq_stack(s2,&temp) == ERR_SQ_STACK_FULL){
printf("s2 栈已满!\n");
break;
}
} TYPE_1 a1; for(int i=; i<; i++){
if(pop_sq_stack(s1,&a1) != ERR_SQ_STACK_NULL){
printf("%d ",a1);
}else{
printf("\ns1 栈已空!\n");
break;
}
} TYPE_2 a2;
for(int i=; i<; i++){
if(pop_sq_stack(s2,&a2) != ERR_SQ_STACK_NULL){
printf("%lf ",a2);
}else{
printf("\ns2 栈已空!\n");
break;
}
} free_sq_stack(s1);
free_sq_stack(s2);
return ;
}
测试结果

C语言实现可复用栈的更多相关文章
- C语言中堆和栈的区别
原文:http://blog.csdn.net/tigerjibo/article/details/7423728 C语言中堆和栈的区别 一.前言: C语言程序经过编译连接后形成编译.连接后形成的二进 ...
- C语言函数参数压栈顺序为何是从右到左?(从左向右的话,碰到printf的会陷入死循环)
上学期学习了汇编语言,并在操作系统实验中使用了汇编+C语言混合编程,中间也了解了一些C语言与汇编语言的对应关系. 由于汇编语言是底层的编程语言,各种函数参数都要直接控制栈进行存取,在混合编程中,要用汇 ...
- C语言简单实现链栈基本几个功能(适合新手看,大神可指正)
接着上一次的顺序栈,今天我记一下链栈,因为我也是刚学不久,有些地方也稍稍理解不了,所以,一起共勉.我会用我自己结合教材上画的图,争取跟代码一起结合,用文字和图最大化的解释代码,这样的话 ...
- [JZOJ3588]【中山市选2014】J语言(表达式解析+栈)
Description J语言作为一门编程语言,诞生于20世纪90年代.............. 好学的小H今天又学到了一种新东西——J语言.显然,J语言的背景已经被小H忘得一干二净了,但是小H仍然 ...
- C语言简单实现链栈基本几个功能
接着上一次的顺序栈,今天我记一下链栈,因为我也是刚学不久,有些地方也稍稍理解不了,所以,一起共勉.我会用我自己结合教材上画的图,争取跟代码一起结合,用文字和图最大化的解释代码,这样的话 ...
- c语言学习,模拟栈操作
1.stack.c模拟栈操作函数的实现 #include<stdio.h> #include<stdlib.h> ; static char *stack;//数据栈 ;//栈 ...
- C++学习(三十二)(C语言部分)之 栈
栈测试代码笔记如下: #include<stdio.h> #include<string.h> #include <stdlib.h> #define SIZE 1 ...
- C++学习(三十一)(C语言部分)之 栈和队列(括号匹配示例)
括号匹配测试代码笔记如下: #include<stdio.h> #include<string.h> #include <stdlib.h> #define SIZ ...
- C++学习(三十)(C语言部分)之 栈和队列
数据结构1.保存数据 2.处理数据数组+操作增查删改 栈和队列是一种操作受限的线性表 栈 是先进后出 是在一端进行插入删除的操作--->栈顶 另一端叫做栈底(栈和栈区是两个概念)(是一种数据结构 ...
随机推荐
- WORD列表缩进的文本起始点
Figure 1 Figure 2 Figure 3 编号位置以刻度尺为起点0.74厘米(2个字符间距),文本缩进以刻度尺为起点2.96厘米(8个字符间距) 以上两者相减得到的值正好=特殊格式悬挂缩进 ...
- [EffectiveC++]item23:Prefer non-member non-friend functions to member functions
99页 导致较大封装性的是non-member non-friend函数,因为它并不增加“能否访问class内之private成分”的函数数量.
- python3程序设计基本方法
实例 6.升级维护 总结: 打了多年的游击战.突然经过教官的指导,觉得很受益,程序自学需要总结和交流.
- Spring(六)之自动装配
一.自动装配模型 下面是自动连接模式,可以用来指示Spring容器使用自动连接进行依赖注入.您可以使用元素的autowire属性为bean定义指定autowire模式. 可以使用 byType 或者 ...
- 新闻cms管理系统 (补)-----路由优化一
修改后台的入口文件,将访问后台页面的入口文件设为admin.php,并且访问该文件的模块默认为admin模块. 添加后台入口文件具体操作步骤: (1)项目目录下新建admin.php (2)实现入口文 ...
- mac系统 IDEA+JFinal+Tomcat+Maven搭建
1.下载Maven(http://maven.apache.org/download.cgi) 2.下载Tomcat(http://tomcat.apache.org/download-90.cgi) ...
- oracle同义词语句备份
--创建同义词create synonym T_SYSTEM_USERDEPARTMENT for xtzl.T_SYSTEM_USERDEPARTMENT;--查询同义词SELECT * FROM ...
- Oracle数据库对表基本的操作--增删查改
--向student表中加入入学时间属性,其数据类型为日期型alter table student add scome date; --删除student表中的入学时间属性alter table st ...
- K3CLOUD开发-动态表单树形单据体实现银行交易对账
背景:系统手机开单生成销售单据,通过银行pos机收款,系统收款流水与银行流水可能存在差异,所以通过获取银行接口,获取消费信息自动插入到生产系统数据库,开发对账报表,实现差异汇总! 展示效果如下: 开发 ...
- webpack+vuecli使用问题总结
1,按照官网安装步骤install $ npm install -g vue-cli $ vue init webpack my-project $ cd my-project $ npm insta ...