
因为在学快排的时候用到栈,针对上一个版本我觉得使用很不方便,所以最近有改良了下,用int,char,int*,char*,char[]数组(字符串类型)时,不用在需要强转指针后在解引用使用了。
如需更完整的解释请访问上一版本传送门
目录
完整代码
stack.h(函数声明)
stack.c(函数实现)
test.c(测试代码)
测试结果
完整代码 stack.h(函数声明)
#pragma once
#define _CRT_SECURE_NO_DEPRECATE 1
#include
#include
#include
#include
#include
#define MAXNUM 4//初始数组大小
typedef struct stack
{
void* _date;//指向自定义数组类型
int _current;//当前元素个数
int _size;//元素最大个数
int _type;//类型占用字节数
void (*clear) (struct stack*);//清空stack的队列,释放内存
void(*push)(struct stack* st, void*);//压栈,增加元素 O(1)
void (*pop)(struct stack* st);//移除栈顶元素 O(1)
int* (*top)(struct stack*);// 取得栈顶元素(但不删除)O(1)
bool (*empty)(struct stack*);// 检测栈内是否为空,空为真 O(1)
int (*size)(struct stack*);//返回stack内元素的个数 O(1)
}stack;
void Stack_clear(stack* st);//清空stack的队列,释放内存
void Stack_Push(stack* st,const void* x);// 压栈,增加元素 O(1)
void Stack_Push_char(stack* st,const char x);
void Stack_Push_Char(stack* st,const char* x);
void Stack_Push_charArray(stack* st, const char* x);
void Stack_Push_int(stack* st, const int x);
void Stack_Push_Int(stack* st, const int* x);
void Stack_pop(stack* st);//移除栈顶元素 O(1)
void* Stack_top(stack* st);// 取得栈顶元素(但不删除)O(1)
char Stack_top_char(stack* st);
char* Stack_top_Char(stack* st);
char* Stack_top_charArray(stack* st);
int Stack_top_int(stack* st);
int* Stack_top_Int(stack* st);
bool Stack_empty(stack* st);//检测栈内是否为空,空为真 O(1)
int Stack_size(stack* st);//返回stack内元素的个数 O(1)
//stack容器初始化函数,st栈的指针,n数据类型大小(字节)
void StackINIT(stack* st,char* arr, ...);
stack.c(函数实现)
#include"stack.h"
void Stack_clear(stack* st)
{
free(st->_date);
st->_date = NULL;
st->_current = 0;
st->_size = 0;
}
//检测是否扩容,并返回需要插入的指针
static void* Capacity(stack* st)
{
if (st->_size == st->_current)//空间已满需要扩容
{
void* _date = realloc(st->_date, st->_size * st->_type * 2);
if (_date == NULL)
{
perror("扩容失败sttor");
exit(-1);
}
else
{
st->_date = _date;
st->_size *= 2;
}
}
char* str1 = (char*)st->_date + st->_type * st->_current;
st->_current++;
return str1;
}
//无类型入栈
void Stack_Push(stack* st,const void* x)// 压栈,增加元素 O(1)
{
memcpy(Capacity(st), x, st->_type);
}
//char型入栈
void Stack_Push_char(stack* st,const char x)
{
*(char*)Capacity(st) = x;
//memcpy(Capacity(st), &x, st->_type);
}
//char*型入栈
void Stack_Push_Char(stack* st,const char* x)
{
*(char**)Capacity(st) = x;
//memcpy(Capacity(st), &x, st->_type);
}
//char[]数组字符串型入栈
void Stack_Push_charArray(stack* st, const char* x)
{
strcpy(Capacity(st),x);
}
//int型入栈
void Stack_Push_int(stack* st, const int x)
{
*(int*)Capacity(st) = x;
}
//int*型入栈
void Stack_Push_Int(stack* st, const int* x)
{
*(int**)Capacity(st) = x;
//memcpy(Capacity(st), &x, st->_type);
}
int[]数组型
//void Stack_Push_int(stack* st, const int *x)
//{
//
//}
//出一个数据
void Stack_pop(struct stack* st)//移除栈顶元素 O(1)
{
if (st->_current > 0)
st->_current--;
}
//无类型取元素
void* Stack_top(struct stack* st)// 取得栈顶元素(但不删除)O(1)
{
char* _date = (char*)st->_date + st->_type * (st->_current - 1);
return _date;
}
//char型取元素
char Stack_top_char(stack* st)
{
return *(char*)Stack_top(st);
}
//char*型取元素
char* Stack_top_Char(stack* st)
{
return *(char**)Stack_top(st);
}
//char[]数组字符串型取元素
char* Stack_top_charArray(stack* st)
{
return (char*)Stack_top(st);
}
//int型取元素
int Stack_top_int(stack* st)
{
return *(int*)Stack_top(st);
}
//int*型取元素
int* Stack_top_Int(stack* st)
{
return *(int**)Stack_top(st);
}
//判断是否为空
bool Stack_empty(struct stack* st)//检测栈内是否为空,空为真 O(1)
{
return !st->_current;
}
//当前最大能存储数据量
int Stack_size(struct stack* st)//返回stack内元素的个数 O(1)
{
return st->_current;
}
//文本转数字
static size_t TurnNumber(char* arr)
{
size_t len = strlen(arr);
size_t num=0;
for (size_t i = 0; i < len; i++)
{
if (arr[i] >= '0' && arr[i] <= '9')
num = num * 10 + arr[i] - '0';
}
return num;
}
//初始化函数
void StackINIT(stack* st,const char* arr, ...)
{
char buf[20];
strcpy(buf, arr);
size_t len = strlen(buf);
//printf("去空格前:%s\n", buf);
//去掉字符串空格
for (size_t i = 0; i < len; i++)
{
if (buf[len-1-i] == ' ')
{
for (size_t j = 0; j < i+1; j++)
{
buf[len - 1 - i+j] = buf[len - i+j];
}
}
}
//printf("去空格后:%s 长度:%d\n", buf,strlen(buf));
if (strcmp(buf, "char")==0)
{
st->_type = sizeof(char);
st->push = Stack_Push_char;//入栈
st->top = Stack_top_char;//取得栈顶元素(但不删除)O(1)
}
else if (strcmp(buf, "char*")==0)
{
st->_type = sizeof(char*);
st->push = Stack_Push_Char;//入栈
st->top = Stack_top_Char;//取得栈顶元素(但不删除)O(1)
}
else if (strncmp(buf, "char[",5) == 0 && buf[strlen(buf) - 1])
{
char num[20];
size_t n = strlen(buf) - 6;
strncpy(num, &buf[5],n );
num[n]='\0';
st->_type = sizeof(char)*TurnNumber(num);
st->push = Stack_Push_charArray;//入栈
st->top = Stack_top_charArray;//取得栈顶元素(但不删除)O(1)
//printf("%d\n", st->_type);
}
else if (strcmp(buf, "int")==0)
{
st->_type = sizeof(int);
st->push = Stack_Push_int;//入栈
st->top = Stack_top_int;//取得栈顶元素(但不删除)O(1)
}
else if (strcmp(buf, "int*")==0)
{
st->_type = sizeof(int*);
st->push = Stack_Push_Int;//入栈
st->top = Stack_top_Int;//取得栈顶元素(但不删除)O(1)
}
//else if (strncmp(buf, "int[", 4) == 0 && buf[strlen(buf) - 1])
//{
// char num[20];
// size_t n = strlen(buf) - 5;
// strncpy(num, &buf[4], n);
// num[n] = '\0';
// st->_type = sizeof(int) * TurnNumber(num);
// st->push = Stack_Push_charArray;//入栈
// st->top = Stack_top_charArray;//取得栈顶元素(但不删除)O(1)
// printf("%d\n", st->_type);
//}
else
{
va_list args;//接收可变参数,
va_start(args, arr);
size_t n = va_arg(args, size_t);//依次访问参数,需指定按照什么类型读取数据
if (n <= 0 || n > 1000)
{
perror("您的类型本程序无内置请输入类型的字符数量,将以void指针形式返回,请强转后解引用使用(上限1000字节)\n");
exit(-1);
}
va_end(args);//参数使用结束
st->_type = n;
st->push = Stack_Push;//入栈
st->top = Stack_top;//取得栈顶元素(但不删除)O(1)
}
st->clear = Stack_clear;//清空stack的队列,释放内存
st->pop = Stack_pop;//出栈
st->empty = Stack_empty;//检测栈内是否为空,空为真 O(1)
st->size = Stack_size;//返回stack内元素的个数 O(1)
st->_current = 0;
st->_date = malloc(st->_type * MAXNUM);
if (st->_date == NULL)
{
perror("初始化sttor失败");
exit(-1);
}
else
{
st->_size = MAXNUM;
}
}
test.c(测试代码)
#include"stack.h"
typedef struct user
{
char name [20];
int age;
}user;
void int_test()
{
stack st;//创建容器
StackINIT(&st,"int");//初始化容器
printf("int类型数据测试\n");
st.push(&st,10);//压栈
st.push(&st, 123);//压栈
st.push(&st,111);//压栈
//st.pop(&st);
st.push(&st, 6565);//压栈
st.push(&st, 100);//压栈
printf("下面为元素遍历\n");
while (!st.empty(&st))
{
printf("%d\n", st.top(&st));
st.pop(&st);
}
printf("stack最大能储存%d个\n\n", st._size);
st.clear(&st);
}
void Int_test()//int指针测试
{
stack st;//创建容器
StackINIT(&st, "int*");//初始化容器
printf("int*类型数据测试\n");
int num1 = 10;
st.push(&st, &num1);//压栈
int num2 = 11;
st.push(&st, &num2);//压栈
int num3 = 12;
st.push(&st,&num3);//压栈
*st.top(&st) = 1000;
printf("下面为元素遍历\n");
while (!st.empty(&st))
{
printf("%d\n", *st.top(&st));
st.pop(&st);
}
printf("stack最大能储存%d个\n\n", st._size);
st.clear(&st);
}
//void int00_test()
//{
// printf("int[]数组类型数据测试\n");
// stack st;//创建容器
// StackINIT(&st, "int[100]");//初始化容器
//}
void char_test()
{
stack st;//创建容器
StackINIT(&st,"char");//初始化容器
printf("char类型数据测试\n");
st.push(&st,'a');//压栈
st.push(&st, 'b');//压栈
st.push(&st, 'c');//压栈
st.push(&st, 'd');//压栈
st.pop(&st);
st.push(&st, 'e');//压栈
st.push(&st, 'f');//压栈
printf("下面为元素遍历\n");
while (!st.empty(&st))
{
printf("%c\n", st.top(&st));
st.pop(&st);
}
printf("stack最大能储存%d个\n\n", st._size);
st.clear(&st);
}
void Char_test()//char指针测试
{
stack st;//创建容器
StackINIT(&st, "char*");//初始化容器
printf("char*类型数据测试\n");
char arr1 = 'a';
st.push(&st, &arr1);//压栈
char arr2 = 'b';
st.push(&st, &arr2);//压栈
char arr3 = 'c';
st.push(&st, &arr3);//压栈
printf("下面为元素遍历\n");
while (!st.empty(&st))
{
printf("%c\n", *st.top(&st));
st.pop(&st);
}
printf("stack最大能储存%d个\n\n", st._size);
st.clear(&st);
}
void char00_test()
{
printf("char[]数组类型数据测试\n");
stack st;//创建容器
StackINIT(&st, "char[100]");//初始化容器
st.push(&st, "玛卡巴卡");//压栈
st.push(&st, "私房菜");//压栈
st.push(&st, "鸭大帅");//压栈
strcpy(st.top(&st), "1231");
printf("下面为元素遍历\n");
while (!st.empty(&st))
{
printf("%s\n",st.top(&st));
st.pop(&st);
}
printf("stack最大能储存%d个\n\n", st._size);
st.clear(&st);
}
void uesr_test()
{
stack st;//创建容器
StackINIT(&st,"user", sizeof(user));//初始化容器
printf("自定义结构体类型数据测试\n");
user us;//创建要压栈的数据变量
strcpy(us.name,"玛卡巴卡");
us.age = 17;
st.push(&st, &us);//压栈
//printf("名字%s,年龄%d\n", (*((user*)st.top(&st))).name, us.age);
strcpy(us.name, "辉小崔");
us.age = 18;
st.push(&st, &us);//压栈
//printf("%c\n", *(int*)st.top(&st));
//st.pop(&st);//出栈
strcpy(us.name, "莫");
us.age = 19;
st.push(&st, &us);//压栈
strcpy(us.name, "唔西迪西");
us.age = 18;
st.push(&st, &us);//压栈
strcpy(us.name, "裂开石榴");
us.age = 20;
st.push(&st, &us);//压栈
printf("元素个数%d\n",st.size(&st));
printf("下面为大佬遍历,年龄瞎写\n");
while (!st.empty(&st))
{
us = *(user*)st.top(&st);
printf("%s大佬,年龄%d\n", us.name,us.age);
st.pop(&st);
}
printf("stack空间大小为%d\n\n", st._size);
st.clear(&st);
}
int main()
{
//int00_test();
char00_test();
int_test();
Int_test();
char_test();
Char_test();
uesr_test();
}
测试结果
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)