《C現代程式設計》第三章 面向物件
阿新 • • 發佈:2018-12-21
3.2 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; }
執行結果如上;
引入校驗器 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; }
執行效果如下:
保證了原有功能的實現,下面是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 開始