C语言实现可复用栈

一、思考

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

二、基本思路

  在我的经验中,栈内的数据不参与运算,对元素的操作只有两种——流入和流出栈。也就是说,数据类型不重要,只要做到正确流入流出即可。(void*)

三、栈的源码

  共2个文件,x_sq_stack.h、x_sq_stack.c。莫纠结前缀x,与代码无任何关系。

 1 /*************************************************************
 2  * x_sq_stack.h
 3  *
 4  * 固定大小的栈,顺序存储
 5  * 把需要的数据类型重命名为s_elemtype即可
 6  *
 7  * **********************************************************/
 8 
 9 #ifndef  X_SQ_STACK_H
10 #define  X_SQ_STACK_H
11 
12 #define OK 0            //pop()、push()函数成功返回
13 #define TRUE 1            //isnull()、isfull()
14 #define FALSE 0            //isnull()、isfull()
15 #define ERR_SQ_STACK_FULL 2    //栈满时push()函数返回
16 #define ERR_SQ_STACK_NULL 3    //栈空时pop()函数返回
17 
18 typedef struct sq_stack{
19     void *base;        //栈空间地址
20     int t_size;        //元素大小(字节数)
21     int size;        //栈大小
22     int top;        //栈顶索引
23 }sq_stack;
24 
25 /***********************************************************
26  *
27  * 创建和销毁栈
28  *
29  * 参数:
30  *  size    栈大小
31  *  t_size  元素大小
32  *
33  * 返回:
34  *  create_..()        不成功返回NULL
35  *
36  * ********************************************************/
37 struct sq_stack * create_sq_stack(int size, int t_size);
38 void free_sq_stack(struct sq_stack *s);
39 
40 /**********************************************************
41  *
42  * 入栈和出栈
43  * 成功都返回OK,不成功分别返回ERR_SQ_STACK_FULL、ERR_SQ_STACK_NULL
44  *
45  * ********************************************************/
46 int push_sq_stack(struct sq_stack *s, const void *data);
47 int pop_sq_stack(struct sq_stack *s, void *data);
48 
49 /**********************************************************
50  *
51  * 判断是否是满栈或空栈
52  * 成立返回TRUE,不成立返回FALSE
53  *
54  * ********************************************************/
55 int isfull_sq_stack(const struct sq_stack *s);
56 int isnull_sq_stack(const struct sq_stack *s);
57 
58 
59 #endif  /*X_SQ_STACK_H*/
 1 /* x_sq_stack.c */
 2 
 3 #include "x_sq_stack.h"
 4 #include <string.h>
 5 #include <stdlib.h>
 6 
 7 
 8 struct sq_stack * create_sq_stack(int size, int t_size)
 9 {
10     struct sq_stack *s;
11     int mem_size = sizeof(struct sq_stack) + size*t_size;
12     if(!(s=(struct sq_stack *)malloc(mem_size))){
13     return NULL;
14     }
15     s->base = (void*)(s+1);
16     s->size = size;
17     s->t_size = t_size;
18     s->top = -1;
19     return s;
20 }
21 
22 void free_sq_stack(struct sq_stack *s)
23 {
24     free(s);
25 }
26 
27 int push_sq_stack(struct sq_stack *s, const void *data)
28 {
29     if(s->top < s->size-1){
30     s->top ++;
31     memcpy(s->base + s->top * s->t_size, data, s->t_size);
32     return OK;
33     }else{
34     return ERR_SQ_STACK_FULL;
35     }
36 }
37 
38 int pop_sq_stack(struct sq_stack *s, void *data)
39 {
40     if(s->top >= 0){
41     memcpy(data, s->base + s->top * s->t_size, s->t_size);
42     s->top --;
43     return OK;
44     }else{
45     return ERR_SQ_STACK_NULL;
46     }
47 }
48 
49 
50 int isfull_sq_stack(const struct sq_stack *s)
51 {
52     if(s->top >= s->size-1) return TRUE;
53     else return FALSE;
54 }
55 
56 int isnull_sq_stack(const struct sq_stack *s)
57 {
58     if(s->top < 0) return TRUE;
59     else return FALSE;
60 }

四、测试

 1 /* main.c */
 2 
 3 #include "x_sq_stack.h"
 4 #include <stdio.h>
 5 
 6 #define TYPE_1 long
 7 #define TYPE_2 double
 8 
 9 int main(int argc, char *argv[])
10 {
11     sq_stack *s1,*s2;
12 
13     s1=create_sq_stack(10,sizeof(TYPE_1));
14     s2=create_sq_stack(10,sizeof(TYPE_2));
15     if(!s1 || !s2){
16     printf("内存分配失败!\n");
17     return 1;
18     }
19 
20     double temp; 
21     for(int i=0; i<20; i++){
22     if(push_sq_stack(s1,&i) == ERR_SQ_STACK_FULL){
23         printf("s1 栈已满!\n");
24     }
25     temp = i/2.1;
26     if(push_sq_stack(s2,&temp) == ERR_SQ_STACK_FULL){
27         printf("s2 栈已满!\n");
28         break;
29     }
30     }
31 
32     TYPE_1 a1;
33 
34     for(int i=0; i<20; i++){
35     if(pop_sq_stack(s1,&a1) != ERR_SQ_STACK_NULL){
36         printf("%d ",a1);
37     }else{
38         printf("\ns1 栈已空!\n");
39         break;
40     }
41     }
42 
43     TYPE_2 a2;
44     for(int i=0; i<20; i++){
45     if(pop_sq_stack(s2,&a2) != ERR_SQ_STACK_NULL){
46         printf("%lf ",a2);
47     }else{
48         printf("\ns2 栈已空!\n");
49         break;
50     }
51     }
52 
53     free_sq_stack(s1); 
54     free_sq_stack(s2); 
55     return 0;
56 }

测试结果

猜你喜欢

转载自www.cnblogs.com/dda9/p/9034009.html