C语言实现可复用栈
2024-09-24 23:25:28
一、思考
最开始写的栈,通过宏来改变元素数据类型,在同一程序中只能用于一种数据类型,想要用于多种数据类型则要复制代码并改名。那么,有没有方法不复制代码就可以用于多种数据类型?
二、基本思路
在我的经验中,栈内的数据不参与运算,对元素的操作只有两种——流入和流出栈。也就是说,数据类型不重要,只要做到正确流入流出即可。(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 ;
}
测试结果
最新文章
- Java JDBC链接数据库
- oracle 12c 创建PDB用户即Local User (PDB与CDB)
- tomcat端口被占用
- ubuntu E: Could not get lock /var/lib/dpkg/lock - open
- (转载)XML Tutorial for iOS: How To Read and Write XML Documents with GDataXML
- jdk源码剖析:Synchronized
- 每天十分钟系列:JS数据操作之神奇的map()
- Django 部署到Nginx
- JAVA进阶之旅(二)——认识Class类,反射的概念,Constructor,Field,Method,反射Main方法,数组的反射和实践
- Java使用URL类下载的图片不完整
- js 动态添加class封装(es6语法)
- 使用mysql设计一个全局订单生产计数器
- Cloudera Manager的安装
- Css3 实现循环留言滚动效果(一)
- vue-8-组件
- maven上传jar包到nexus私服后的存放路径 以及 使用IDEA上传jar包的步骤
- cloudstack 添加新网卡使其能上网
- nth-of-type和nth-child
- R语言缺失值高级处理方法
- @Java类加载的过程
热门文章
- [EffectiveC++]item41:了解隐式接口和编译器多态
- Selenium2+python自动化
- python安装 numpy&;安装matplotlib&; scipy
- 枚举类型与位域枚举Enum
- UVa 10735 - Euler Circuit(最大流 + 欧拉回路)
- 智慧监狱来了!SaCa EMM 助推现代监狱建设迈上新台阶
- [Python 多线程] Barrier (十一)
- CUDA 纹理的使用
- linux下搭建LAMP
- week9:Recommender Systems