#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 1024
//栈:注意和动态数组的区别:
//动态数组这里用的指针是二级指针因为数组的大小无法提前确定,并且用户数组类型无法确定,要用void*一级指针来接收
//所以要在堆区动态开辟数组存放void*类型数据要用二级指针来接收
//这里的栈已经知道数组的最大长度,因此不需要再用在堆区再次开辟一块内存来用二级指针指向
struct sStack
{
//因为不确定用户数据类型,所以用void*指针来接收用户输入的数据地址
//指针数组----里面存放的是地址或者指针
void* data[MAX];
int size;
};
//隐藏数据,不让用户能够得到操作结构体的接口
//类似c++类中的private属性
typedef void* seqStack;
//初始化栈----返回栈的结构体,为了隐藏数据用万能指针作为返回值
seqStack init_stack()
{
//为栈结构体开辟空间
sStack* stack = (sStack*)malloc(sizeof(sStack));
if (stack == NULL)
{
return NULL;
}
//初始化数组--清空数组,一开数组里面会有随机值
memset(stack->data,NULL,sizeof(void*)*MAX);
//长度初始哈
stack->size = 0;
//返回栈的结构体
return stack;
}
//入栈
void push_stack(seqStack stack,void* data)
{
//尾插
if (stack == NULL)
return;
if (data == NULL)
return;
//把传入的void*数据转为sStack*数据类型
sStack* mystack = (sStack*)stack;
//判断当前栈内元素是否超过最大容量
if (mystack->size == MAX)
{
return;
}
//下面从数组尾部开始插入
mystack->data[mystack->size] =data;
//长度加一
mystack->size++;
}
//出栈:尾删
void pop_stack(seqStack stack)
{
if (stack == NULL)
return;
sStack* mystack = (sStack*)stack;
if (mystack->size == 0)
return;
//尾删:将数组中最后一个元素置空---把指针置空
//这里指针置空后相当于断掉了指针指向用户的数据,相当于做了删除操作
//因为我们这里不清楚用户的数据是开辟在堆区还是栈区
mystack->data[mystack->size - 1] = NULL;
//更新长度
mystack->size--;
}
//返回栈顶元素
seqStack top_stack(seqStack stack)
{
if (stack == NULL)
return NULL;
sStack* mystack = (sStack*)stack;
if (mystack->size == 0)
return NULL;
return mystack->data[mystack->size-1];
}
//返回栈的大小
int size_stack(seqStack stack)
{
if (stack == NULL)
return -1;
sStack* mystack = (sStack*)stack;
return mystack->size;
}
//判断栈是否为空
bool empty_stack(seqStack stack)
{
if (stack == NULL)
return true;//表示为空
sStack* mystack = (sStack*)stack;
if (mystack->size == 0)
return -1;//为空
return 0;//不为空
}
//销毁栈
void destroy_stack(seqStack stack)
{
if (stack == NULL)
return;
//只有栈结构体分配到堆区
free(stack);
}
//测试代码:
//--------------------------------------------
struct person
{
char name[32];
int age;
};
int main()
{
seqStack stack=init_stack();
person p1 = {"大忽悠",19 };
person p2 = { "like",18 };
person p3 = {"小朋友",19 };
//入栈
push_stack(stack, &p1);
push_stack(stack, &p2);
push_stack(stack, &p3);
//通过出栈的操作来遍历
while (empty_stack(stack)==false)
{
//弹出栈顶后
person *p=(person*)top_stack(stack);
printf("姓名:%s\t年龄:%d\n",p->name,p->age);
//出栈
pop_stack(stack);
}
//返回栈的元素个数
int size = size_stack(stack);
printf("元素个数:%d\n", size);
//
return 0;
}