⭐栈的多种实现,这样传参是否可以实现了?

本文探讨了两种数据结构——顺序表和单向链表如何用于实现栈,并深入剖析了它们在函数参数传递中的应用。通过实例代码展示,解释了为何这种传参方式在理论上不可行,揭示了指针在栈操作中的关键作用和潜在问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

⭐栈的多种实现方式,这样传参是否可以实现了?

顺序表实现

Stack.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

//用顺序表来实现栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;
	int capacity;
}ST;

void StackInit(struct Stack* st);
void StackDestory(struct Stack* st);
void StackPush(struct Stack* st,STDataType x);
STDataType StackTop(struct Stack* st);
void StackPop(struct Stack* st);
bool StackEmpty(struct Stack* st);
int  StackSize(struct Stack* st);

Stack.c

void StackInit(struct Stack* st)
{
	assert(st);
	st->a = NULL;
	st->top = 0;
	st->capacity = 0;
	
}
void StackDestory(struct Stack* st)
{
	assert(st);
	//while (st->top!=0)
	//{
	//	//st->a这个是一块连续的空间,释放时应该写
	//	//成free(st->a),应该他空间是连续的,像我
	//	//这种写法就是错误的
	//	free(st->a[st->top-1]);      
	//	st->top--;
	//}
	if (st->a)
	{
		free(st->a);
	}
	st->a = NULL;
	st->top = 0;
	st->capacity = 0;
}
void StackPush(struct Stack* st, STDataType x)
{
	assert(st);
	if (st->top == st->capacity)
	{
		if (st->top == 0)
		{
			st->capacity += 4;
		}
		else
		{
			st->capacity *= 2;
		}
/*		//最好不要这样写,万一创建失败了,创建失败
		//就不能直接给st->a了,所以最好有个临时变量
		//来过渡一下
		st->a = (STDataType*)realloc(st->a, sizeof(STDataType)* 4);
		//细节方面,最好加上,防止创建失败
		if (st->a == NULL)
		{
			printf("realloc failed\n");
			exit(-1);
		}
*/
		//较好的写法
		STDataType* temp = (STDataType*)realloc(st->a, sizeof(STDataType)* 4);
		if (temp == NULL)
		{
			printf("realloc failed\n");
			exit(-1);
		}
		else
		{
			st->a = temp;
		}
	}
	st->a[st->top] = x;
	st->top++;
}
STDataType StackTop(struct Stack* st)
{
	assert(st);
	//万一栈为空了,所以这种情况也要断言一下
	assert(!StackEmpty(st));
	return st->a[st->top - 1];
}
void StackPop(struct Stack* st)
{
	assert(st);
	//万一栈为空了,所以这种情况也要断言一下
	assert(!StackEmpty(st));
	--st->top;
}
bool StackEmpty(struct Stack* st)
{
	assert(st);
	return st->top == 0;
}
int  StackSize(struct Stack* st)
{
	assert(st);
	return st->top;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"stack.h"
void test1()
{
	struct Stack st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	StackPush(&st, 3);
	StackPush(&st, 4);
	printf("%d\n",StackTop(&st));
	StackPop(&st);
	printf("%d\n", StackTop(&st));
	StackPop(&st);
	StackPush(&st, 5);
	printf("%d\n", StackTop(&st));
	StackPop(&st);
	while (!StackEmpty(&st))
	{
		printf("%d", StackTop(&st));
		StackPop(&st);
	}
	printf("\n");
	//这一步一定不能忘了,不然会出现内存泄漏
	StackDestory(&st);
	
}

单向链表实现

Stack.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>



//用单链表的方式来实现栈
typedef int STDataType;
typedef struct Stack
{
	STDataType data;
	struct Stack* next;
}ST;

//二级指针的传法
void StackInit(struct Stack** phead);
void StackDestory(struct Stack* phead);
void StackPush(struct Stack** phead, STDataType x);
STDataType StackTop(struct Stack** phead);
void StackPop(struct Stack** phead);
bool StackEmpty(struct Stack** phead);
int  StackSize(struct Stack* phead);

Stack.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"8-5.h"
//二级指针的版本
void  StackInit(struct Stack** phead)
{
	*phead = (struct Stack*)malloc(sizeof(struct Stack));
	if (*phead == NULL)
	{
		printf("malloc failed\n");
		exit(-1);
	}
	(*phead)->data = -1;
	(*phead)->next = NULL;
}
void StackDestory(struct Stack* phead)
{
	assert(phead);
	struct Stack* cur = phead;
	while (cur)
	{
		free(phead);
		cur = cur->next;
		phead = cur;
	}
}
void StackPush(struct Stack** phead, STDataType x)
{
	assert(*phead);
	struct Stack* newnode = (struct Stack*)malloc(sizeof(struct Stack));
	if (newnode == NULL)
	{
		printf("malloc failed\n");
	}
	else
	{
		newnode->data = x;
		newnode->next = *phead;
		*phead = newnode;
	}
}
STDataType StackTop(struct Stack** phead)
{
	assert(phead);
	return (*phead)->data;
}
void StackPop(struct Stack** phead)
{
	assert(*phead);
	struct Stack* newphead = (*phead)->next;
	free(*phead);
	*phead = newphead;
}
bool StackEmpty(struct Stack** phead)
{
	return *phead == NULL;
}
int  StackSize(struct Stack* phead)
{
	int n = 0;
	struct Stack* cur = phead;
	while (cur)
	{
		++n;
		cur = cur->next;
	}
	return n;
}

Test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"8-5.h"


  void test2()
{
	/*这种是用二级指针来解决的,stack8-4的
	那种是用返回值来解决的,下面写一种用一级指针来解决的*/
	struct Stack* phead;    
	StackInit(&phead);
	StackPush(&phead, 0);
	StackPush(&phead, 1);
	StackPush(&phead, 2);
	StackPush(&phead, 3);
	StackPop(&phead);
	StackPush(&phead, 4);
	while (!StackEmpty(&phead))
	{
		printf("%d ", StackTop(&phead));
		StackPop(&phead);
	}
}
    

int main()
{
	/*test1();*/
	test2();
	return 0;
}

这样传参可以实现吗?

我们会发现很多数据结构实现时,它一开始传的都是一个结构体指针,包括这儿也是,很多用单向链表实现栈的代码中,一开始传的都是结构体指针的地址。在这里插入图片描述
但是你是否思考过,如果这儿一开始这样传参可以实现吗(前提是后面函数中的代码没有错误)?在这里插入图片描述
我在这儿可以很明确的告诉你,在后面函数中的代码没有错误的情况下,用这种写法也是肯定不可能实现的?在之后我会写一期专门将指针的博客,那儿会揭晓具体的原因,读者可以先思考一下为什么。

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个数学不怎么好的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值