当前位置: 代码迷 >> 综合 >> 写一个堆栈(OPC原则+校验器)-强烈推荐!!!
  详细解决方案

写一个堆栈(OPC原则+校验器)-强烈推荐!!!

热度:7   发布时间:2023-12-12 15:14:31.0

了解更多知识请点我:学习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原则思想指导下,我们这边可以轻松的创建相似的函数。美妙!!!

结果

在这里插入图片描述

  相关解决方案