一、思考

  最开始写的栈,通过宏来改变元素数据类型,在同一程序中只能用于一种数据类型,想要用于多种数据类型则要复制代码并改名。那么,有没有方法不复制代码就可以用于多种数据类型?

二、基本思路

  在我的经验中,栈内的数据不参与运算,对元素的操作只有两种——流入和流出栈。也就是说,数据类型不重要,只要做到正确流入流出即可。(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 ;
}

测试结果

最新文章

  1. Java JDBC链接数据库
  2. oracle 12c 创建PDB用户即Local User (PDB与CDB)
  3. tomcat端口被占用
  4. ubuntu E: Could not get lock /var/lib/dpkg/lock - open
  5. (转载)XML Tutorial for iOS: How To Read and Write XML Documents with GDataXML
  6. jdk源码剖析:Synchronized
  7. 每天十分钟系列:JS数据操作之神奇的map()
  8. Django 部署到Nginx
  9. JAVA进阶之旅(二)——认识Class类,反射的概念,Constructor,Field,Method,反射Main方法,数组的反射和实践
  10. Java使用URL类下载的图片不完整
  11. js 动态添加class封装(es6语法)
  12. 使用mysql设计一个全局订单生产计数器
  13. Cloudera Manager的安装
  14. Css3 实现循环留言滚动效果(一)
  15. vue-8-组件
  16. maven上传jar包到nexus私服后的存放路径 以及 使用IDEA上传jar包的步骤
  17. cloudstack 添加新网卡使其能上网
  18. nth-of-type和nth-child
  19. R语言缺失值高级处理方法
  20. @Java类加载的过程

热门文章

  1. [EffectiveC++]item41:了解隐式接口和编译器多态
  2. Selenium2+python自动化
  3. python安装 numpy&amp;安装matplotlib&amp; scipy
  4. 枚举类型与位域枚举Enum
  5. UVa 10735 - Euler Circuit(最大流 + 欧拉回路)
  6. 智慧监狱来了!SaCa EMM 助推现代监狱建设迈上新台阶
  7. [Python 多线程] Barrier (十一)
  8. CUDA 纹理的使用
  9. linux下搭建LAMP
  10. week9:Recommender Systems