栈的实现、与static

在实现栈的通用性过程中遇到的问题(段错误)
先上代码

seqstack.h
#ifndef STACK_H
#define STACK_H

#include <stdbool.h>

// 该程序模块提供栈的功能
// 默认处理的是int数据
// 用户如需处理其他自定义数据,请定义如下宏,如:
// #define SEQSTACK_NODE xxx

// 如果用户没有自定义顺序栈元素类型
// 那么类型默认为int
#ifndef SEQSTACK_NODE 
#define SEQSTACK_NODE int
#endif

typedef SEQSTACK_NODE datatype;

// 顺序栈的管理结构体
typedef struct seqstack
{
	int size;
	int top;

	datatype *data;
}stack;

// 以下是栈的操作接口

// 初始化
// size: 初始状态下,空栈的容量
stack * init_stack(int size);

// 入栈
// 成功返回真,失败(当栈已满的时候)返回假
bool push(stack *s, datatype data);

// 出栈: 将栈顶元素删除
// 成功返回真,失败(当栈为空的时候)返回假
bool pop(stack *s);

// 读取栈顶: 将栈顶元素返回
bool top(stack *s, datatype *pdata);

// 判断满
bool full(stack *s);

// 判断空
bool empty(stack *s);

#endif
seqstack.c
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>

#include "seqstack.h"

// 栈的初始化
// 成功时,返回栈的管理结构体指针
// 失败时,返回NULL
stack * init_stack(int size)
{
	// 申请栈的管理结构体
	stack * s = malloc(sizeof(stack));
	if(s != NULL)
	{
		s->size = size;
		s->top  = -1;
		
		s->data = calloc(size, sizeof(datatype));
		if(s->data == NULL)
		{
			free(s);
			return NULL;
		}
	}

	return s;
}

// 入栈: 将数据data,置入栈s的栈顶中
bool push(stack *s, datatype data)
{
	// 栈已满,无法置入
	if(full(s))
		return false;

	s->data[++s->top] = data;
	return true;
}

// 出栈: 将栈顶元素删除
bool pop(stack *s)
{
	if(empty(s))
		return false;

	s->top--;
	return true;
}

// 取栈顶元素
bool top(stack *s, datatype *pdata)
{
	if(empty(s))
		return false;

	*pdata = s->data[s->top];
	return true;
}

// 判断栈是否已满、是否为空
bool empty(stack *s)
{
	return s->top == -1;
}

bool full(stack *s)
{
	return s->top == s->size-1;
}

//使用默认参数测试代码、程序正常执行 OK

test.c
#include <stdio.h>
#include "seqstack.h"

int main(void)
{
	stack *s = init_stack(10);

	push(s, 1);
	push(s, 2);
	push(s, 3);
	push(s, 4);
	push(s, 5);
	
	// 应该输出54321
	int c;
	while(!empty(s))
	{
		top(s, &c);
		printf("%d", c);

		pop(s);
	}
	printf("\n");

	return 0;
}

通过以上你以为程序没有bug吗?
再看看使用一下代码测试(自定义类型参数)

test_char.c
#include <stdio.h>

#define SEQSTACK_NODE char
#include "seqstack.h"

int main(void)
{
	stack *s = init_stack(10);

	push(s, 'a');
	push(s, 'b');
	push(s, 'c');
	push(s, 'd');
	push(s, 'e');
	
	// 应该输出edcba
	char c;
	while(!empty(s))
	{
		top(s, &c);
		printf("%c", c);

		pop(s);
	}
	printf("\n");

	return 0;
}

以上代码似乎没有什么错误,但是这会产生段错误。
下面分析一下段错误产生的原因及解决方法:

![在这里插入图片描述](https://img-blog.csdnimg.cn/20200511083156719.bmp?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xHV1hVUA==,size_16,color_FFFFFF,t_70)
总结一下:seqstack.c 与test_char.c 的数据类型不同,导致段错误
解决方法:将seqstack.c 的代码放置到seqstack.h,即将它们合为1个.h 文件即可。并将函数声明为static,因为static函数才能在头文件中定义实现。
缺点:无法将.h文件变为动态库。
如有不对,恳请指正!
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值