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.处理数据数组+操作增查删改 栈和队列是一种操作受限的线性表 栈 是先进后出 是在一端进行插入删除的操作--->栈顶 另一端叫做栈底(栈和栈区是两个概念)(是一种数据结构 ...
随机推荐
- redis下的持久化保存
rdb.h rdb.c ---> 完成数据保存到临时文件,再利用rename保存到指定文件的过程: 如果需要写一个数据持久化保存的功能时,可以参考这部分代码: //rdb API int ...
- Economy a Two-Edged Sword for Democrats
2017-05-03 12:05:07 https://www.usnews.com/news/blogs/ken-walshs-washington/2014/10/03/economy-a-two ...
- Python 及其基础语法
重新开始玩 Python,打算就是学完实验楼的"Python3 简明教程",然后就可以玩点小项目,先前学了点 Python2 就不管它啦. 以上. 认识 Python Python ...
- Vim 编辑器及其基本操作
实验楼某些课程有用 Vim 编辑器来写代码,因此有了这篇博客,据说是上古神器,当然主要目的是基本操作. Vim 编辑器 Vim(Vi IMprove) 是 Linux 系统上的最著名的文本/代码编辑器 ...
- c++计算器后续(3)
自娱自乐: 本来只是想改改第二次的代码规范的,然后好像把原来的代码玩坏了,真是尴尬...然后大概是又发现了一些东西.以上. main的参数: 大概是说main函数的括号里是可以带参数的,写成这个样子: ...
- [TOP10]最受欢迎的10个Metasploit模块和插件
很多人都想知道最受欢迎的10个Metasploit模块和插件是什么(TOP10),事实上这是一个很难回答的问题,因为什么才叫"Top"?我想每个人都有每个人的看法.于是我们通过调查 ...
- python面向对象之类成员
面向对象编程: OOP编程是利用类和对象来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得简单,并可以大大提高程序开发效率.另外,基于面向对象的程序可 ...
- GAutomator,GAutomatorview和Android SDK,Unity配置
1. 安装和配置JDK 环境配置中: JAVA_HOME:E:\Program Files\java\jdk1.8.0_131 Path:%JAVA_HOME%\bin;%JAVA_HOME%\jre ...
- fread与fread_s读取文件(二进制文件)
fread()是c库函数,利于移植,使用缓存,效率较read()高. 原型: size_t fread(void *buffer, size_t size, size_t count, FILE * ...
- HDU 1213(裸并查集)(无变形)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1213 How Many Tables Time Limit: 2000/1000 MS (Java/ ...