StackStruct.h
/**********************************************************************************
* @file StackStruct.h
* @brief 栈结构及其常用操作API(C语言实现)
*
* @attention
*
* @note
*
* @version V1.0
* V1.1
* - a.修改部分变量、参数的命名;
* - b.修改、删除部分注释;
* - c.更改错误码枚举;
* - d.修改PopStack()函数,弹出元素不再用return返回,使用指针参数返回,避免疏忽造成的内存泄漏问题。
* @date 2024-03-22
**********************************************************************************/
#ifndef __STACK_STRUCT__H_
#define __STACK_STRUCT__H_
#define StackStruct_MAX_SIZE 100 // 栈内存大小
#pragma pack(1)
typedef enum
{
__Stack_SUCCESSFUL = 0, // 操作成功,非满,非空
__Stack_FAILEDL = -1, // 操作失败
__Stack_Is_EMPTY = 1001, // 栈空
__Stack_Is_FULL = 1002, // 栈满
__Stack_ERR_CODE_END
}E_StackErrCode;
// 栈结构
typedef struct
{
void* aElements[StackStruct_MAX_SIZE];
int nTopIndex;
} T_Stack;
#pragma pack()
/**********************************************************************************
* @brief 创建空栈
*
* @param
*
* @return - T_Stack*
*
* @details
*
* @note
**********************************************************************************/
T_Stack* CreateStack();
/**********************************************************************************
* @brief 判断栈是否空
*
* @param - T_Stack* ptStack)
*
* @return - __SUCCESSFUL 非空
* - __FAILED 空
* - __ABNORMAL 其它异常
*
* @details
*
* @note
**********************************************************************************/
int StackIsEmpty(T_Stack* ptStack);
/**********************************************************************************
* @brief 判断栈是否满
*
* @param - T_Stack* ptStack)
*
* @return - __SUCCESSFUL 非满
* - __FAILED 满
* - __ABNORMAL 其它异常
*
* @details
*
* @note
**********************************************************************************/
int StackIsFull(T_Stack* ptStack);
/**********************************************************************************
* @brief 入栈操作
*
* @param - T_Stack* ptStack
* - void* nNum
*
* @return - __SUCCESSFUL 正常入栈
* - __FAILED 入栈异常
*
* @details
*
* @note - 在C语言中,将整数(常量)直接强制转换为void*类型的指针是不安全的,
* - 会导致段错误。如果想将整数压入栈中,应该先将整数存储在一个合适大小
* - 的数据结构中(如int型变量),然后再将该变量的地址强制转换为void*类
* - 型的指针。
* - 错误示范:PushStack(stack, (void*)&10)
* - 正确示范:int nNum=10; PushStack(stack, (void*)&nNum);
**********************************************************************************/
int PushStack(T_Stack* ptStack, void* nNum);
/**********************************************************************************
* @brief 出栈操作
*
* @param - T_Stack* ptStack
* - void* pPopElement
*
* @return - __SUCCESSFUL 弹出成功
* - __FAILED 异常
*
* @details
*
* @note - 在弹栈时,需要将void*类型的指针转换回相应的数据类型,以便正确读取
* - 它的值。
* - 正确示范:*(int*)PopStack(stack)
**********************************************************************************/
int PopStack(T_Stack* ptStack, void** pPopElement);
#endif // __STACK_STRUCT__H_
StackStruct.c
#include <stdio.h> // printf
#include <stdlib.h> // malloc
#include "StackStruct.h"
T_Stack* CreateStack()
{
T_Stack* ptStack = (T_Stack*)malloc(sizeof(T_Stack)); // 为栈分配内存
if (NULL == ptStack)
{
printf("<stack><create> Memory allocation failed.\n");
return NULL;
}
ptStack->nTopIndex = -1; // 将栈设置为空
return ptStack;
}
int StackIsEmpty(T_Stack* ptStack)
{
if (-1 == ptStack->nTopIndex) // 栈空
{
printf("<stack><isEmpty> stack is empty.\n");
return __Stack_Is_EMPTY;
}
else if (0 <= ptStack->nTopIndex)
{
printf("<stack><isEmpty> stack top index = %d.\n", ptStack->nTopIndex);
return __Stack_SUCCESSFUL;
// return ptStack->nTopIndex;
}
else
{
printf("<stack><isEmpty> stack abnormal, stack top index = %d.\n", ptStack->nTopIndex);
return __Stack_FAILEDL;
}
}
int StackIsFull(T_Stack* ptStack)
{
if ((StackStruct_MAX_SIZE-1) <= ptStack->nTopIndex) // 栈满
{
printf("<stack><isFull> stack is full.\n");
return __Stack_Is_FULL;
}
else if ((StackStruct_MAX_SIZE-1) > ptStack->nTopIndex)
{
printf("<stack><isFull> stack top index = %d.\n", ptStack->nTopIndex);
return __Stack_SUCCESSFUL;
// return ptStack->nTopIndex; // 返回栈顶索引有bug,当栈顶索引为-1时,返回值是-1,判满函数被调用时,会误认为栈满
}
else
{
printf("<stack><isFull> stack abnormal.\n");
return __Stack_FAILEDL;
}
}
int PushStack(T_Stack* ptStack, void* pNum)
{
int nResult = StackIsFull(ptStack);
if (__Stack_SUCCESSFUL != nResult) // 栈满或异常
{
printf("<stack><push><error> stack is full or abnormal, StackIsFull() return result = %d.\n", nResult);
return __Stack_FAILEDL;
}
++ptStack->nTopIndex;
ptStack->aElements[ptStack->nTopIndex] = pNum;
return __Stack_SUCCESSFUL; // 入栈成功
}
int PopStack(T_Stack* ptStack, void** pElement)
{
int nResult = StackIsEmpty(ptStack);
if (__Stack_SUCCESSFUL != nResult)
{
printf("<stack><pop><error> stack is empty or abnormal, StackIsEmpty() return result = %d.\n", nResult);
return __Stack_FAILEDL;
}
*pElement = ptStack->aElements[ptStack->nTopIndex];
--ptStack->nTopIndex;
return __Stack_SUCCESSFUL; // 出栈成功
}