了解更多知识请点我:学习C语言之路(汇总篇)
需求分析
- 字符栈
- 栈顶元素
- 创建一个栈
- 销毁一个栈
- 压栈
- 弹出栈
- 返回栈中的数据个数
- 判断栈是否为空
- 判断栈是否满
代码分析
#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>
#define MAXSIZE 100
//- 字符栈
//- 栈顶元素
//- 创建一个栈
//- 销毁一个栈
//- 压栈
//- 弹出栈
//- 返回栈中的数据个数
//- 判断栈是否为空
//- 判断栈是否满struct stackCDT{
int *data;size_t top;size_t numData;
};
typedef struct stackCDT *stackADT;stackADT newStack()
{
stackADT pdata;pdata = (stackADT)malloc(sizeof(struct stackCDT));pdata->data = (int*)malloc(MAXSIZE*sizeof(int)) ;pdata->top = 0;pdata->numData = MAXSIZE;return pdata;
}void freeStack(stackADT pdata)
{
free(pdata->data);free(pdata);
}bool stackFull(stackADT pdata)
{
return (pdata->top == pdata->numData);
}
bool stackEmpty(stackADT pdata)
{
return (pdata->top == 0);
}bool pushStack(stackADT pdata,size_t *value)
{
if(stackFull(pdata))return false;pdata->data[pdata->top++] = *value;return true;
}
bool popStack(stackADT pdata,size_t *value)
{
if(stackEmpty(pdata))return false;*value = pdata->data[--pdata->top];return true;
}size_t getstackADTDepth(stackADT pdata)
{
return (pdata->top);
}
bool getstackADTElement(stackADT pdata,size_t size,size_t *value)
{
if(size>(pdata->top))return false;*value = pdata->data[pdata->top-size ];return true;
}int main()
{
int temp = 1;int temp1 = 0;stackADT stack1 = newStack();if(pushStack(stack1,&temp));printf("%d\n",getstackADTDepth(stack1));printf("push OK\n");if(popStack(stack1,&temp1))printf("temp1= %d\n",temp1);printf("%d\n",getstackADTDepth(stack1));freeStack(stack1);
}
注意点
bool popStack(stackADT pdata,size_t *value)
{
if(stackEmpty(pdata))return false;*value = pdata->data[--pdata->top];return true;
}
这个执行的时候 要先–pdata->top 而不是pdata->top --。
新需求
假设只允许0到9之内的数据push到栈中怎么办呢,
- 范围校验器
- 奇偶校验器
我们这边写代码就要是使用以下原则
开闭原则(OPC,Open-Closed Princple)
一个模块应该要“对扩展开放,对修改关闭”。
push范围检验器代码
bool pushRangCheck(stackADT pdata,int *value,int min,int max)
{
if(*value<min ||*value >max)return false;return pushStack(pdata,value);
}
范围校验器(请先看下链接)
C语言从零写个校验器(很牛的校验器)
最终版
#include <stdio.h>
#include <malloc.h>
#include <stdbool.h>#define newRangeValidator(min, max) {
(RangCheck), (min), (max)}
#define newOddEvenValidator(isEven) {
(OddCheck), (isEven)}#define MAXSIZE 100
//- 字符栈
//- 栈顶元素
//- 创建一个栈
//- 销毁一个栈
//- 压栈
//- 弹出栈
//- 返回栈中的数据个数
//- 判断栈是否为空
//- 判断栈是否满struct stackCDT{
int *data;size_t top;size_t numData;
};
typedef struct stackCDT *stackADT;
typedef bool (*const Validate)(void *pthis,int value);//变量先定义
typedef struct{
Validate pdata;size_t min;size_t max;
}St_RangCheck;
typedef struct {
Validate pdata;size_t odd;
}St_OddCheck;bool RangCheck(void *pdata,int value)
{
St_RangCheck *pRang =(St_RangCheck *)pdata;return (value>(pRang->min) && value<(pRang->max));
}
bool OddCheck(void *pdata,int value)
{
St_OddCheck *pRang =(St_OddCheck *)pdata;return (value%(pRang->odd) == 0);
}bool ValidateCheck(void *pdata ,int value)
{
Validate range = *(Validate *)pdata; return range(pdata,value);
}stackADT newStack()
{
stackADT pdata;pdata = (stackADT)malloc(sizeof(struct stackCDT));pdata->data = (int*)malloc(MAXSIZE*sizeof(int)) ;pdata->top = 0;pdata->numData = MAXSIZE;return pdata;
}void freeStack(stackADT pdata)
{
free(pdata->data);free(pdata);
}bool stackFull(stackADT pdata)
{
return (pdata->top == pdata->numData);
}
bool stackEmpty(stackADT pdata)
{
return (pdata->top == 0);
}bool pushStack(stackADT pdata,size_t *value)
{
if(stackFull(pdata))return false;pdata->data[pdata->top++] = *value;return true;
}
bool popStack(stackADT pdata,size_t *value)
{
if(stackEmpty(pdata))return false;*value = pdata->data[--pdata->top];return true;
}size_t getstackADTDepth(stackADT pdata)
{
return (pdata->top);
}
bool getstackADTElement(stackADT pdata,size_t size,size_t *value)
{
if(size>(pdata->top))return false;*value = pdata->data[pdata->top-size ];return true;
}bool pushRangCheck(stackADT pdata,int *value,int min,int max)
{
if(*value<min ||*value >max)return false;return pushStack(pdata,value);
} bool PushValidateCheck(stackADT sdata,void *pdata ,int value)
{
Validate range = *(Validate *)pdata; if(range(pdata,value)){
pushStack(sdata,&value);return true;}else{
return false;}
} int main()
{
int temp = 1;int temp1 = 0;St_RangCheck rangcheck = newRangeValidator(0,10);stackADT stack1 = newStack();if(PushValidateCheck(stack1,&rangcheck,2))printf("%d\n",getstackADTDepth(stack1));printf("push OK\n");if(popStack(stack1,&temp1))printf("temp1= %d\n",temp1);printf("%d\n",getstackADTDepth(stack1));freeStack(stack1);
}
程序详解
- 原代码部分:
bool pushRangCheck(stackADT pdata,int *value,int min,int max)
{
if(*value<min ||*value >max)return false;return pushStack(pdata,value);
}
- 新增代码部分:
bool PushValidateCheck(stackADT sdata,void *pdata ,int value)
{
Validate range = *(Validate *)pdata; if(range(pdata,value)){
pushStack(sdata,&value);return true;}else{
return false;}
}
解释说明
在OPC原则思想指导下,我们这边可以轻松的创建相似的函数。美妙!!!