C/C++学习记录——静态常量

一、井字棋小游戏

  一般情况下,简单的陈述性知识会让我们觉得,自己对学的每一个知识点都掌握了。但是结果往往是是脑子会了,手还不会。所以,今天复习C++编程的时候直接用一个小程序来体现。大家都玩过井字棋吧,一种非常无聊且简单的游戏。现在我们用C++的面向对象的特点来完成这个小小的游戏。注:不是图形界面的编程

二、构建井字棋类

  简单思考一下,我们就会发现,井字棋的类里面应该包含:存储所有胜利情况、棋盘当前状况、用户当前下棋状态等变量,以及判断用户是否胜利的方法。基于此我们可以把现在定义的类写出来。

class C{
public:
	char places[10];//棋盘当前状态
	char winway[8][3];//胜利的方式
private:
	char myWay[7];//每个人最多可以走
public:
	C();
	~C();//析构函数
	void playing(char ch);//正在下棋
	bool isWinner();//判断是否获胜
	bool matching();//比较参赛者是否胜利
};

  我们来观察上面的这个类定义,首先下棋是胜利方式,不应该是一个玩家单独遵守的,而是所有玩井字棋游戏的玩家共同遵守的。其次,咱们的棋盘状态也应该是玩家共有的。所以我们应该把这两个变量修改为整个类共同拥有的状态。整个类共同拥有的意思就是,我们可以直接用类的名称来访问该变量,而不是用对象来访问。举一个简单的例子,现在我们有一个类,假设就是狗类。现在我们要统计所有狗的个数,那么我们就可以设计一个容器,每当有一个狗对象产生了,我们就加一。这个容器应该和类一起产生和消亡,并且应该只会申请一次空间。  C++为我们提供这类共有变量的方法是:静态变量static。所以我们应该把上面的类重新定义为:

class C{
public:
	static char places[10];//棋盘状态
private:
	char myWay[7];//每个人最多可以走5步
	static char winway[8][3];  //胜利方式
public:
	C();
	~C();//析构函数
	void playing(char ch);//正在下棋
	bool isWinner();//判断是否获胜
	bool matching();//比较参赛者是否胜利
}

然后,我们刚才也提到了胜利方式的应该是不变的,即在程序运行的过程中,它不允许被改变。于是我们还要用到关键字:const。所以类的完整定义应该是:

class C{
public:
	static char places[10];
private:
	char myWay[7];//每个人最多可以走5步
	static const char winway[8][3];
public:
	C();
	~C();//析构函数
	void playing(char ch);//正在下棋
	bool isWinner();//判断是否获胜
	bool matching();//比较参赛者是否胜利
}

三、具体实现

  代码实现的逻辑很简单,就不在赘述。

代码

//////////////////////////////////
//////////////头文件/////////////
#ifndef _JCHESS_H_
#define _JCHESS_H_
class C{
public:
	static char places[10];
private:
	char myWay[7];//每个人最多可以走5步
	static const char winway[8][3];
public:
	C();
	~C();//析构函数
	void playing(char ch);//正在下棋
	bool isWinner();//判断是否获胜
	bool matching();//比较参赛者是否胜利
};
bool place(char* way,char ch);
#endif
//////////////////////////////////////
////////////头文件源文件//////////////
#include 
#include 
#include "jchess.h"
const char C::winway[8][3]={{'1','2','3'},{'4','5','6'},{'7','8','9'},{'1','5','9'},{'3','5','7'},{'1','4','7'},{'2','5','8'},{'3','6','9'}};//获胜的可能性
char C::places[10]="123456789";
C::C()
{
	myWay[0] = 0;//记录每个人下棋的步数
}
C::~C(){}//析构函数
void C::playing(char ch)//下棋
{
	myWay[0]+=1;
	int index = myWay[0];
	myWay[index] = ch;
}
bool C::isWinner()//判段胜负
{
	if(myWay[0]>2)//只有大于下期3次以上才可以判断胜负
	{
		return matching();
	}
	else
		return false;
}
bool C::matching()
{
	int i,j,k=0;//数组的变量
	int match;//匹配的长度
	for(i = 0;i<8;i++)
	{
		match = 0;
		for(j=0;j<3;j++)
		{
			for(k=1; k<=(int)myWay[0]; k++)
			{
			if(C::winway[i][j] == myWay[k])
			{
				++match;//匹配度加一
			}
		}		

		if(match == 3) 
		{
			return true;
		}
	}
	if(match == 3) 
	{
		return true;
	}
}
return false;

}
bool place(char* way,char ch)
{
int index = ch-'0'-1;//下棋的位置
if(way[index]==0)
{
return false;
}
way[index] = 0;
return true;

}
/////////////////////////////////////////
/////////////主函数//////////////////////

include

include"jchess.h"

using namespace std;
int main()
{
C a,b;
int count = 0;
bool wa=false,wb=false;
while(!wa || !wb)
{
char ai,bi;
cout<<"请用户A下棋:"<<endl;
cin>>ai;
while(! place(C::places,ai))//必须是没有下棋的位置
{
cout<<"该位置已经下棋,重新下棋:"<<endl;
cin>>ai;
}
a.playing(ai);
++count;
if(a.isWinner())
{
cout<<"A用户胜利!"<<endl;
return 1;
}
if(count>=9)
{
cout<<"平局"<<endl;
return 1;
}
cout<<"请用户B下棋:"<<endl;
cin>>bi;
while(! place(C::places,bi))//必须是没有下棋的位置
{
cout<<"该位置已经下棋,重新下棋:"<<endl;
cin>>bi;
}
++count;
b.playing(bi);
if(b.isWinner())
{
cout<<"B用户胜利!"<<endl;
return 1;
}
}
}

四、const使用

4.1使用规则

  1、必须注意静态类变量或者常类变量,应该在类外声明。

const char C::winway[8][3]={{'1','2','3'},{'4','5','6'},{'7','8','9'},{'1','5','9'},{'3','5','7'},{'1','4','7'},{'2','5','8'},{'3','6','9'}};//获胜的可能性
char C::places[10]="123456789";

4.2使用情况

1、尽量用const替代程序中/#define。因为,预定义定义实在编译的时候处理的,所以我们定义的符号并没有出现在符号里面,导致程序出现错误。还有就是使用使用#define可能会出现多个变量副本的出现。
2、const char* p代表的静态常量p;char* const p代表静态指针。
3、对于很多不可变的变量一定要记得加上const。

原文地址:https://www.cnblogs.com/kadcyh/p/14475835.html