3.2 C的模块化与面向对象
本章主要是将C 的知识模块化,用结构体把数据和操作函数分离开来,将函数发布对外使用,这就是面向对象 的思想,也是C++的思想;
生成一个栈的结构体 ,包括栈的元素;栈的初始化newStack(),栈的压入push(); 栈的取出pop()
stack.h 文件
#ifndef _STACK_H_ #define _STACK_H_ #include <stddef.h> #ifdef _cplusplus extren "C" { #endif typedef struct { int top; const size_t size; int *const pBuf; }Stack; bool push(Stack *p , int val); bool pop(Stack *p, int *pRet); #define newStack(buf){ \ 0, \ sizeof(buf) / sizeof(int), \ buf \ } #ifdef _cplusplus } #endif #endif
注意:
- 使用extern "C"可使C++顺利调用C函数,同时#ifdef __cplusplus是为了告诉编译器,extern "C" 仅在C++中编译时才有效。C++标准规定了在C++中编译时,__cplusplus标示符才会被定义,如下:#ifdef __cplusplus
extern "C"
{
#endif
//中间代码
#ifdef __cplusplus
}
#endif
宏定义时候用的 \ 是连接的意思。
stack.cpp 文件
#include "stack.h" static bool isNull(void *p) { if (NULL == p) { return true; } return false; } static bool isStackFull(Stack *p) { if (p->top == p->size) { return true; } else { return false; } } static bool isStackEmpty(Stack *p) { if (0 == p->top) { return true; } else { return false; } } //成功返回true;失败返回false bool push(Stack *p, int val) { if (isStackFull(p)) { return false; } else { p->pBuf[p->top++] = val; } return true; } //成功返回true;失败返回false bool pop(Stack *p, int *pRet) { if (isStackEmpty(p)||isNull(pRet)) { return false; } else { *pRet = p->pBuf[--p->top]; } return true; }
我们输出运行一下
#include<stdio.h> #include "stack.h" int main() { int buf[16]; Stack stack = newStack(buf); for (int i = 1; i < 18;i++) { if (!push(&stack, i)) { printf("stack is full !\n"); } } int buff[16]; for (int i = 0; i < 16;i++) { if (pop(&stack , &buff[i])) { printf("buff[%d]:%d\n", i ,buff[i]); } } return 0; }
可以看出栈是压入的,取出是从顶部取出来。
3.2.1 设置压入范围
stack.h 文件
#ifndef _STACK_H_ #define _STACK_H_ //生成一个栈的结构体 #include <stddef.h> #ifdef _cplusplus extren "C" { #endif typedef struct { const int min; const int max; }Range; typedef struct { int top; const size_t size; int *const pBuf; const Range* const pRange; }Stack; bool push(Stack *p , int val); bool pop(Stack *p, int *pRet); #define newStack(buf){ \ 0, \ sizeof(buf) / sizeof(int), \ buf, \ NULL \ } #define newStackWitchRange(buf , pRange){ \ 0, \ sizeof(buf) / sizeof(int), \ buf, \ pRange \ } #ifdef _cplusplus } #endif #endif
stack.cpp 文件
#include "stack.h" static bool isNull(void *p) { if (NULL == p) { return true; } return false; } static bool isStackFull(Stack *p) { if (p->top == p->size) { return true; } else { return false; } } static bool isStackEmpty(Stack *p) { if (0 == p->top) { return true; } else { return false; } } //输入范围检擦 static bool isRangeOk(const Range *p , int val) { if (isNull((void *)p) || (p->max >= val && val >= p->min)) { return true; } return false; } //成功返回true;失败返回false bool push(Stack *p, int val) { if (isStackFull(p) || !isRangeOk( p->pRange, val)) { return false; } else { p->pBuf[p->top++] = val; } return true; } //成功返回true;失败返回false bool pop(Stack *p, int *pRet) { if (isStackEmpty(p)||isNull(pRet)) { return false; } else { *pRet = p->pBuf[--p->top]; } return true; }
mian .cpp 文件
#include<stdio.h> #include "stack.h" int main() { int buf[16]; Range range = {0 , 9};// Stack stack = newStackWitchRange(buf, &range);// for (int i = 1; i < 18;i++) { if (!push(&stack, i)) { printf("stack is full !\n"); } } int buff[16]; for (int i = 0; i < 16;i++) { if (pop(&stack , &buff[i])) { printf("buff[%d]:%d\n", i ,buff[i]); } } return 0; }
Range range = {0,9} 是初始化一个Range结构体;
Stack stack = newStackWitchRange(buf, &range); 初始化Stack的结构体;
这样stack 的结构体中就会有 pRang 指针,指向 range = { 0 ,9} 的结构体;
运行结果如上;
引入校验器 Validtor
stack.h 文件
#ifndef _STACK_H_ #define _STACK_H_ //生成一个栈的结构体 #include <stddef.h> #ifdef _cplusplus extren "C" { #endif typedef struct Validator { bool(*const validate)(struct Validator *pThis , int val); void *pData; }Validator;//添加 typedef struct { const int min; const int max; }Range; typedef struct { int previousValue; }PreviousValue;//添加 typedef struct { int top; const size_t size; int *const pBuf; //const Range* const pRange; Validator *const pValidator;//添加 }Stack; bool push(Stack *p , int val); bool pop(Stack *p, int *pRet); bool validateRange(Validator *pThis , int val);//添加 bool vaidatePrevious(Validator *pThis, int val);//添加 #define newStack(buf){ \ 0, \ sizeof(buf) / sizeof(int), \ buf, \ NULL \ } #define rangeValidator(pRange){\ validateRange,\ pRange\ }/*对应函数bool validateRange(Validator *pThis , int val)*/ #define previousValidator(pPrevious){\ vaidatePrevious,\ pPrevious\ }/*bool vaidatePrevious(Validator *pThis, int val);*/ #define newStackWitchValidator(buf , pValidator){ \ 0, \ sizeof(buf) / sizeof(int), \ buf, \ pValidator \ }//修改 #ifdef _cplusplus } #endif #endif
stack.cpp 文件
#include "stack.h" static bool isNull(void *p) { if (NULL == p) { return true; } return false; } static bool isStackFull(Stack *p) { if (p->top == p->size) { return true; } else { return false; } } static bool isStackEmpty(Stack *p) { if (0 == p->top) { return true; } else { return false; } } //输入范围检擦,【函数失效】 //static bool isRangeOk(const Range *p , int val) //{ // if (isNull((void *)p) || (p->max >= val && val >= p->min)) // { // return true; // } // return false; //} bool validateRange(Validator *pThis, int val)//添加 { if (!isNull(pThis)) { Range *pRange = (Range *)pThis->pData; if (pRange->max >= val && val >= pRange->min) { return true; } } return false; } bool vaidatePrevious(Validator *pThis, int val)//添加 { if (!isNull(pThis)) { PreviousValue *pPrevious = (PreviousValue *)pThis->pData; if (val > pPrevious->previousValue) { pPrevious->previousValue = val; return true; } } return false; } //成功返回true;失败返回false bool push(Stack *p, int val) { if (isStackFull(p) || !(p->pValidator->validate(p->pValidator , val))) { return false; } else { p->pBuf[p->top++] = val; } return true; } //成功返回true;失败返回false bool pop(Stack *p, int *pRet) { if (isStackEmpty(p)||isNull(pRet)) { return false; } else { *pRet = p->pBuf[--p->top]; } return true; }
main.cpp 文件
#include<stdio.h> #include "stack.h" int main() { int buf[16]; Range range = {0 , 15}; Validator validator = rangeValidator(&range);//添加 Stack stack = newStackWitchValidator(buf, &validator);//修改 for (int i = 1; i < 17;i++) { if (!push(&stack, i)) { printf("stack is full !\n"); } } int buff[16]; for (int i = 0; i < 16;i++) { if (pop(&stack , &buff[i])) { printf("buff[%d]:%d\n", i ,buff[i]); } } return 0; }
过程解说下,先初始化一个Range 的结构体,将它用于初始化Validator 的 pDate指针;
函数指针指向的是 validateRange(‘’)的函数;
所以结构体 stack 中的 Validator *const pValidator 指针,它是连接数据和函数操作的指针;
运行效果如下:
保证了原有功能的实现,下面是PreviousValitoar 校验器的使用:
#include<stdio.h> #include "stack.h" int main() { int buf[16]; //Range range = {0 , 15}; //Validator validator = rangeValidator(&range);//添加 PreviousValue Previous = {9}; Validator validator = previousValidator(&Previous);//添加 Stack stack = newStackWitchValidator(buf, &validator);//修改 for (int i = 1; i < 17;i++) { if (!push(&stack, i)) { printf("stack is full !\n"); } } int buff[16]; for (int i = 0; i < 16;i++) { if (pop(&stack , &buff[i])) { printf("buff[%d]:%d\n", i ,buff[i]); } } return 0; }
运行效果下图
实现两种验证器合并 :
stack.h文件
#ifndef _STACK_H_ #define _STACK_H_ //生成一个栈的结构体 #include <stddef.h> #ifdef _cplusplus extren "C" { #endif typedef struct Validator { bool(*const validate)(struct Validator *pThis , int val); void *pData; }Validator;// typedef struct { const int min; const int max; }Range; typedef struct { int previousValue; }PreviousValue;// typedef struct { Range *Pange; PreviousValue *Previous; }RangeWithPrevious;//添加 typedef struct { int top; const size_t size; int *const pBuf; //const Range* const pRange; Validator *const pValidator;// }Stack; bool push(Stack *p , int val); bool pop(Stack *p, int *pRet); bool validateRange(Validator *pThis , int val);// bool vaidatePrevious(Validator *pThis, int val);// bool vaidateRangePrevious(Validator *pThis, int val);//添加 #define newStack(buf){\ 0,\ sizeof(buf) / sizeof(int),\ buf,\ NULL\ } #define rangeValidator(pRange){\ validateRange,\ pRange\ }/*对应函数bool validateRange(Validator *pThis , int val)*/ #define previousValidator(pPrevious){\ vaidatePrevious,\ pPrevious\ }/*bool vaidatePrevious(Validator *pThis, int val);*/ #define rangePreviousValidator(pRangePrevious){\ vaidateRangePrevious,\ pRangePrevious\ }/*bool vaidateRangePrevious(Validator *pThis, int val);*/ #define newStackWitchValidator(buf , pValidator){\ 0,\ sizeof(buf) / sizeof(int),\ buf,\ pValidator\ } #ifdef _cplusplus } #endif #endif
stack.cp 文件
#include "stack.h" static bool isNull(void *p) { if (NULL == p) { return true; } return false; } static bool isStackFull(Stack *p) { if (p->top == p->size) { return true; } else { return false; } } static bool isStackEmpty(Stack *p) { if (0 == p->top) { return true; } else { return false; } } //输入范围检擦,【函数失效】 //static bool isRangeOk(const Range *p , int val) //{ // if (isNull((void *)p) || (p->max >= val && val >= p->min)) // { // return true; // } // return false; //} bool validateRange(Validator *pThis, int val)// { if (!isNull(pThis)) { Range *pRange = (Range *)pThis->pData; if (pRange->max >= val && val >= pRange->min) { return true; } } return false; } bool vaidatePrevious(Validator *pThis, int val)// { if (!isNull(pThis)) { PreviousValue *pPrevious = (PreviousValue *)pThis->pData; if (val > pPrevious->previousValue) { pPrevious->previousValue = val; return true; } } return false; } bool vaidateRangePrevious(Validator *pThis, int val)//添加 { if (!isNull(pThis)) { RangeWithPrevious *pPreviousRange = (RangeWithPrevious *)pThis->pData; if ((val >pPreviousRange->Previous->previousValue) &&(pPreviousRange->Pange->max >= val && val >= pPreviousRange->Pange->min)) { return true; } } return false; } //成功返回true;失败返回false bool push(Stack *p, int val) { if (isStackFull(p) || !(p->pValidator->validate(p->pValidator , val))) { return false; } else { p->pBuf[p->top++] = val; } return true; } //成功返回true;失败返回false bool pop(Stack *p, int *pRet) { if (isStackEmpty(p)||isNull(pRet)) { return false; } else { *pRet = p->pBuf[--p->top]; } return true; }
mian.cpp 文件
#include<stdio.h> #include "stack.h" int main() { int buf[16]; Range range = {0 , 15};// //Validator validator = rangeValidator(&range); PreviousValue Previous = {2}; RangeWithPrevious rangePrevious = { &range, &Previous }; Validator validator = rangePreviousValidator(&rangePrevious); Stack stack = newStackWitchValidator(buf, &validator); for (int i = 1; i < 17;i++) { if (!push(&stack, i)) { printf("stack is full !\n"); } } int buff[16]; for (int i = 0; i < 16;i++) { if (pop(&stack , &buff[i])) { printf("buff[%d]:%d\n", i ,buff[i]); } } return 0; }
运行结果如下:
可以从运行结果上看出输入范围在 0··15 之间,输入必须从 大于 的2 开始