1. 程式人生 > >《C現代程式設計》第三章 面向物件

《C現代程式設計》第三章 面向物件

 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 開始