电脑为什么会下象棋?

电脑为什么会下象棋?,第1张

我是学计算机的,呵呵,其实这个问题很有趣的呢^_^

中国的象棋我还不是很清楚,我目前所知道的最牛的机子名叫【深蓝】,战胜了国际象棋大师【卡斯帕罗夫】,详细资料如下

http://www.wst.net.cn/history/5.11/10.htm

其实,计算机本身是没有只能的,之所以他能够拥有下棋的能力,是因为我们预先教会了他,通过程序语言,实现了我们跟计算机之前的对话,就好像我们告诉他:

如果别人走马,你就走马,如果别人走象,你就走象一样……

在计算机中,是通过程序语言来实现的,格式是

if......then......

else if......then.......

就跟上面的如果怎么样就怎么样是一样的了,这样计算机就懂得在不同情况下如何处理了哦^_^

希望姐姐的解释还比较清晰^_^

【补充来了】^_^

思路1,平均每方每步游拦可有35种走法。50回合。

思路2,棋盘上90个点,各点可走的点。如车可以走到任意一点。

按照思路一的算法 往多了算

一盘棋有50回合,也就是100步,每步有50种变化

一共的变化数就是50的100次方

就算少算一点

一盘棋有20回合,也就是40步,每步10种变化

一共的变化数是10的40次方

这个数也足够大了,就是1后面跟着40个0

【也就是说,别人走了旁薯一步以后,你有多少种可能的走法,计算机会去计算,然后择优录取】

给你个算法吧,我们实验课上经常做这些^_^

#include "StdAfx.h"

#include "Calculate.h"

#include "MantisChessThink.h"

#include "string.h"

#include "stdio.h"

/*************************************************************************

把Think重新包装一下,进行坐标变换,希望神启胡以后其他人的算法的接口都采用这个函数

这样的编译出来的DLL可以直接替换原来的CChessThinker.dll

timespan是思考的限定时间,以毫秒为单位,时间不同可能导致不同的思考策略。

本程序中的算法没有使用这一变量。

**************************************************************************/

BOOL Calculate(char* map,int timespan,int&x1,int&y1,int&x2,int&y2)

{

//BOOL Thinking(int tmap[11][12],POINT tmanposition[32],int &tside,int &resultman, POINT &resultpoint)

int tmap[11][12]

POINT manpoint[32]

int side=(int)map[0]-48

int resultman=32

POINT resultpoint={0,0}

for (int i = 0i <11i++)

{

for (int j = 0j <12j++)

{

tmap[i][j] = 32

}

}

for (int i = 0i <32i++)

{

manpoint[i].x=0

manpoint[i].y=0

}

int length=(int)strlen(map)

int index = 1

while (index <length)

{

int x =1 + ((int)map[index + 0]-48)//thinking的x从1到9

int y = 10 - ((int)map[index + 1]-48)//thinking的y从10到1

int color = (int)map[index + 2]-48//0-RED,1-BLAVK

int type = (int)map[index + 3]-48//0-6

int manIndex=0

if (color==0)

{

switch (type)

{

case 0:

manIndex=0

break

case 1:

if (manpoint[1].x==0) manIndex=1

else manIndex=2

break

case 2:

if (manpoint[3].x==0) manIndex=3

else manIndex=4

break

case 3:

if (manpoint[5].x==0) manIndex=5

else manIndex=6

break

case 4:

if (manpoint[7].x==0) manIndex=7

else manIndex=8

break

case 5:

if (manpoint[9].x==0) manIndex=9

else manIndex=10

break

case 6:

if (manpoint[11].x==0) manIndex=11

else if (manpoint[12].x==0) manIndex=12

else if (manpoint[13].x==0) manIndex=13

else if (manpoint[14].x==0) manIndex=14

else manIndex=15

break

}

}

else

{

switch (type)

{

case 0:

manIndex=16

break

case 1:

if (manpoint[17].x==0) manIndex=17

else manIndex=18

break

case 2:

if (manpoint[19].x==0) manIndex=19

else manIndex=20

break

case 3:

if (manpoint[21].x==0) manIndex=21

else manIndex=22

break

case 4:

if (manpoint[23].x==0) manIndex=23

else manIndex=24

break

case 5:

if (manpoint[25].x==0) manIndex=25

else manIndex=26

break

case 6:

if (manpoint[27].x==0) manIndex=27

else if (manpoint[28].x==0) manIndex=28

else if (manpoint[29].x==0) manIndex=29

else if (manpoint[30].x==0) manIndex=30

else manIndex=31

break

}

}

manpoint[manIndex].x=x

manpoint[manIndex].y=y

tmap[x][y]=manIndex

index += 4

}

//ShowInt(side)

//ShowInt(resultman)

//ShowInt(resultpoint.x)

//ShowInt(resultpoint.y)

BOOL b=Think( tmap,manpoint,side,resultman,resultpoint)

if (b)

{

x1=manpoint[resultman].x-1

y1=10-manpoint[resultman].y

x2=resultpoint.x-1

y2=10-resultpoint.y

}

return b

//return FALSE

}

BOOL test(char* x1)

{

return FALSE

}

void ShowInt(int i)

{

char buf[256]

sprintf(buf,"%d",i)

MessageBox(NULL,buf,"test",0)

}

void ShowString(char * t)

{

MessageBox(NULL,t,"test",0)

}

/ CChessThink.cpp : 定义 DLL 应用程序的入口点。

//

#include "stdafx.h"

#ifdef _MANAGED

#pragma managed(push, off)

#endif

BOOL APIENTRY DllMain( HMODULE hModule,

DWORD ul_reason_for_call,

LPVOID lpReserved

)

{

return TRUE

}

#ifdef _MANAGED

#pragma managed(pop)

#endif

Calculate.h

void ShowInt(int i)

void ShowString(char * t)

BOOL Calculate(char* map,int timespan,int&x1,int&y1,int&x2,int&y2)

MantisChessDef.h

const int MW=32,SW=1//MW-棋子宽度SW-棋子间隔的一半

const int BWA=MW+SW*2//BWA-棋格宽度

const int XBW=BWA*9,YBW=BWA*10//棋盘的长宽

const int MAN=0//人

const int COM=1//计算机

const int RED=0//红方

const int BLACK=1//黑方

const int RED_K=0//红帅

const int RED_S=1//仕

const int RED_X=2//相

const int RED_M=3//马

const int RED_J=4//车

const int RED_P=5//炮

const int RED_B=6//兵

const int BLACK_K=7//黑将

const int BLACK_S=8//士

const int BLACK_X=9//象

const int BLACK_M=10//马

const int BLACK_J=11//车

const int BLACK_P=12//炮

const int BLACK_B=13//卒

//以下是全局函数定义:

//把棋子序号转换为对应图标的序号

const int ManToIcon[33]= {0,1,1,2,2,3,3,4,4,5,5,6,6,6,6,6

,7,8,8,9,9,10,10,11,11,12,12,13,13,13,13,13,-1}

//棋子类型与图标的序号相同

#define ManToType ManToIcon

const int ManToType7[33]= {0,1,1,2,2,3,3,4,4,5,5,6,6,6,6,6

,0,1,1,2,2,3,3,4,4,5,5,6,6,6,6,6,-1}

//随即函数,返回小于n的随机整数

int rnd(const int&n)

//给出棋子序号!!,判断是红是黑

const int SideOfMan[33]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,-1}

const int _defaultmap[11][12]=

{

// [0][1][2][3][4][5][6][7][8][9][10][11]

{32,32,32,32,32,32,32,32,32,32,32,32},//[0]

{32,32,32,32,32,32,32,32,32,32,32,32},//[1]

{32,32,32,32,32,32,32,32,32,32,32,32},//[2]

{32,32,32,32,32,32,32,32,32,32,32,32},//[3]

{32,32,32,32,32,32,32,32,32,32,32,32},//[4]

{32,32,32,32,32,32,32,32,32,32,32,32},//[5]

{32,32,32,32,32,32,32,32,32,32,32,32},//[6]

{32,32,32,32,32,32,32,32,32,32,32,32},//[7]

{32,32,32,32,32,32,32,32,32,32,32,32},//[8]

{32,32,32,32,32,32,32,32,32,32,32,32},//[9]

{32,32,32,32,32,32,32,32,32,32,32,32}//[10]

}

const int FistOfSide[2]={0,16}

const int LastOfSide[2]={15,31}

const int MAXMOVE = 1000

struct MOVEHISTORY

{

int count

int man[MAXMOVE]

POINT from[MAXMOVE]

POINT to[MAXMOVE]

int betaken[MAXMOVE]

}

#include "StdAfx.h"

#include "MantisChessDef.h"

#include "MantisChessThink.h"

//-------------下面几项可以调试智能模块---------------------------

#define S_WIDTH 8

#define S_DEPTH 6

// 将 士 象 马 车 炮 兵

const int base[7]= {300,400,300,600, 1000,600,300}//平均价值

const int range[7]= {0 , 0, 0, 20, 10, 0, 50}//价值的变动范围

const int contactpercent1=20//防守的重视程度

const int contactpercent2=25//进攻的重视程度

/******************************************************************

例:把马设为平均价值200,变动范围±13%应设base[3]=200,range[3]=13

*******************************************************************/

//-----------------------------------------------------------------

const int BV1[7]=//基本价值

{

base[0]-base[0]*range[0]/100,

base[1]-base[1]*range[1]/100,

base[3]-base[2]*range[2]/100,

base[3]-base[3]*range[3]/100,

base[4]-base[4]*range[4]/100,

base[5]-base[5]*range[5]/100,

base[6]-base[6]*range[6]/100

}

const int BV2[7]=//活跃度

{

2*base[0]*range[0]/100/4,

2*base[1]*range[1]/100/4,

2*base[2]*range[2]/100/4,

2*base[3]*range[3]/100/8,

2*base[4]*range[4]/100/17,

2*base[5]*range[5]/100/17,

0,

}

const int BV3[5]=//兵在不同位置的价值附加

{

0*2*base[6]*range[6]/100/4,

1*2*base[6]*range[6]/100/4,

2*2*base[6]*range[6]/100/4,

3*2*base[6]*range[6]/100/4,

4*2*base[6]*range[6]/100/4,

}

#define NORED(i,j) (SideOfMan[tmap[i][j]]!=0)

#define NOBLACK(i,j) (SideOfMan[tmap[i][j]]!=1)

#define NOMAN(i,j) (tmap[i][j]==32)

//兵卒在不同位置的价值,数字越大价值越高

const int ManBPlus[2][12][11]=

{

{

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

{ 0, 1, 2, 3, 4, 4, 4, 3, 2, 1, 0},

{ 0, 1, 2, 3, 4, 4, 4, 3, 2, 1, 0},

{ 0, 1, 2, 3, 3, 3, 3, 3, 2, 1, 0},

{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},

{ 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0},

{ 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

},

{

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

{ 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0},

{ 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0},

{ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0},

{ 0, 1, 2, 3, 3, 3, 3, 3, 2, 1, 0},

{ 0, 1, 2, 3, 4, 4, 4, 3, 2, 1, 0},

{ 0, 1, 2, 3, 4, 4, 4, 3, 2, 1, 0},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},

{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

}

}

//-------------------------------------------

static void ContactV(int tmap[11][12],POINT tmanposition[32],int &tside,int activity[32],int contact[32][32])

/******************************************************************

Mantis_QuickSort:对走法列表进行快速排序

参数:

A: 关键值

chessman: 待排序的棋子列表

targetpoint: 待排序的目标点列表

low,high: QuickSort上下限

返回值: 无

******************************************************************/

void Mantis_QuickSort(int A[],int chessman[],POINT targetpoint[],int low,int high)

{

int pivot

int pivot_man

POINT pivot_point

int scanUp,scanDown

int mid,k

POINT point

if(high-low<=0)

{

return

}

else

{

if(high-low==1)

{

if(A[high]>A[low])

{

k=A[high]

A[high]=A[low]

A[low]=k

k=chessman[high]

chessman[high]=chessman[low]

chessman[low]=k

point=targetpoint[high]

targetpoint[high]=targetpoint[low]

targetpoint[low]=point

return

}

}

}

mid=(low +high)/2

pivot=A[mid]

pivot_man=chessman[mid]

pivot_point=targetpoint[mid]

k=A[mid]

A[mid]=A[low]

A[low]=k

k=chessman[mid]

chessman[mid]=chessman[low]

chessman[low]=k

point=targetpoint[mid]

targetpoint[mid]=targetpoint[low]

targetpoint[low]=point

scanUp =low+1

scanDown = high

do{

while(scanUp<=scanDown &&A[scanUp]>=pivot)

scanUp++

while(pivot>A[scanDown])

scanDown--

if(scanUp<scanDown)

{

k=A[scanUp]

A[scanUp]=A[scanDown]

A[scanDown]=k

k=chessman[scanUp]

chessman[scanUp]=chessman[scanDown]

chessman[scanDown]=k

point=targetpoint[scanUp]

targetpoint[scanUp]=targetpoint[scanDown]

targetpoint[scanDown]=point

}

}while(scanUp<scanDown)

A[low]=A[scanDown]

A[scanDown]=pivot

chessman[low]=chessman[scanDown]

chessman[scanDown]=pivot_man

targetpoint[low]=targetpoint[scanDown]

targetpoint[scanDown]=pivot_point

if(low<scanDown-1)

Mantis_QuickSort(A,chessman,targetpoint,low,scanDown-1)

if(scanDown+1<high)

Mantis_QuickSort(A,chessman,targetpoint,scanDown+1,high)

}

/******************************************************************

Value: 估值函数

参数:

tmap: 各棋位状态

tmanposition: 32棋子的坐标

tside: 轮到哪一放走

返回值: 局面的价值

******************************************************************/

int Value(int tmap[11][12],POINT tmanposition[32],int &tside)

{

static int k

static int ManExtValue[32]

static int ManBaseValue[32]

static int ManContact[32][32]

static int BeAteCount[32]

static BOOL OwnSee[32]

ZeroMemory(ManContact,sizeof(int)*32*32)

ZeroMemory(ManBaseValue,sizeof(int)*32)

ZeroMemory(ManExtValue,sizeof(int)*32)

ZeroMemory(BeAteCount,sizeof(int)*32)

ZeroMemory(OwnSee,sizeof(int)*32)

int maxvalue=0

int i,j

ContactV(tmap,tmanposition,tside,ManBaseValue,ManContact)

//己方将军

for(i=FistOfSide[tside]i<=LastOfSide[tside]i++)

{

if(ManContact[i][FistOfSide[!tside]])

{

maxvalue=9700

return maxvalue

}

}

for(i=0i<32i++)

{

k=ManToType7[i]

ManBaseValue[i]=BV1[k]+ManBaseValue[i]*BV2[k]

switch(k)

{

case 6: ManBaseValue[i]+=BV3[ ManBPlus[SideOfMan[i]][tmanposition[i].y][tmanposition[i].x] ]

break

}

}

for(i=0i<32i++)

{

for(j=0j<32j++)

{

if(ManContact[i][j])

{

if(SideOfMan[i]==SideOfMan[j])

{

BeAteCount[j]++

if(!OwnSee[j])

{

ManExtValue[i]+=ManBaseValue[j]*contactpercent1/100//己方

OwnSee[j]=TRUE

}

}

else

{

ManExtValue[i]+=ManBaseValue[j]*contactpercent2/100//对方

BeAteCount[j]--

}

}

}

}

for(i=FistOfSide[tside]i<=LastOfSide[tside]i++)

{

if(tmanposition[i].x)maxvalue+=ManBaseValue[i]+ManExtValue[i]

}

static BOOL flag

flag=FALSEk=32

for(i=FistOfSide[!tside]i<=LastOfSide[!tside]i++)

{

if(tmanposition[i].x)maxvalue-=ManBaseValue[i]+ManExtValue[i]

//对方将军

if(ManContact[i][FistOfSide[tside]])

{

flag=TRUE

k=i

break

}

}

if(flag&&BeAteCount[k]>=0)//被将,所将军的棋子不能被吃掉

{

j=0

for(i=FistOfSide[tside]i<=LastOfSide[tside]i++)

{

if(BeAteCount[i]<0 &&ManBaseValue[i]>j)

j=ManBaseValue[i]

}

maxvalue -=j

}

else

{

j=0

for(i=FistOfSide[!tside]i<=LastOfSide[!tside]i++)

{

if(BeAteCount[i]<0 &&ManBaseValue[i]>j)

j=ManBaseValue[i]

}

maxvalue +=j

}

return maxvalue

}

/******************************************************************

EnumList: 列出所有走法

参数:

tmap: 各棋位状态

tmanposition: 32棋子的坐标

tside: 轮到哪一放走

chessman: 指向棋子列表的指针(存放结果)

move: 指向棋子所走到位置的指针,与chessman一起组成走法列表

(存放结果)

count: 走法的总数(存放结果)

返回值: “照相”返回TRUE,否则返回FALSE

******************************************************************/

BOOL EnumList(int tmap[11][12],POINT tmanposition[32],int &tside,int *chessman,POINT *move,int &count)

{

#define ADD(man,tx,ty) {chessman[count]=manmove[count].x=txmove[count].y=tycount++if(tmap[tx][ty]==FistOfSide[!tside])goto _NOKING}

static int i,j,n,x,y

static BOOL flag

count=0

for(n=FistOfSide[tside]n<=LastOfSide[tside]n++)

{

x=tmanposition[n].x

if(!x)continue

y=tmanposition[n].y

switch(n)

{

case 0:

if(tmanposition[0].x==tmanposition[16].x) //将帅在同一列

{

flag=FALSE

for(j=tmanposition[16].y+1j<tmanposition[0].yj++)

{

if(tmap[x][j]!=32)

{

flag=TRUE

break

}

}

if (!flag)

{

ADD(0,x,tmanposition[16].y)

}

}

j=y+1if(j<=10 &&NORED(x,j)) ADD(0,x,j)

j=y-1if(j>=8 &&NORED(x,j)) ADD(0,x,j)

i=x+1if(i<=6 &&NORED(i,y)) ADD(0,i,y)

i=x-1if(i>=4 &&NORED(i,y)) ADD(0,i,y)

break

case 16:

if(tmanposition[0].x==tmanposition[16].x) //将帅在同一列

{

flag=FALSE

for(j=tmanposition[16].y+1j<tmanposition[0].yj++)

{

if(tmap[x][j]!=32)

{

flag=TRUE

break

}

}

if (!flag)

{

ADD(16,x,tmanposition[0].y)

}

}

j=y+1if(j<=3 &&NOBLACK(x,j)) ADD(16,x,j)

j=y-1if(j>=1 &&NOBLACK(x,j)) ADD(16,x,j)

i=x+1if(i<=6 &&NOBLACK(i,y)) ADD(16,i,y)

i=x-1if(i>=4 &&NOBLACK(i,y)) ADD(16,i,y)

break

case 1:

case 2:

i=x+1j=y+1if(i<=6 &&j<=10 &&NORED(i,j)) ADD(n,i,j)

i=x+1j=y-1if(i<=6 &&j>=8 &&NORED(i,j)) ADD(n,i,j)

i=x-1j=y+1if(i>=4 &&j<=10 &&NORED(i,j)) ADD(n,i,j)

i=x-1j=y-1if(i>=4 &&j>=8 &&NORED(i,j)) ADD(n,i,j)

break

case 17:

case 18:

i=x+1j=y+1if(i<=6 &&j<=3 &&NOBLACK(i,j)) ADD(n,i,j)

i=x+1j=y-1if(i<=6 &&j>=1 &&NOBLACK(i,j)) ADD(n,i,j)

i=x-1j=y+1if(i>=4 &&j<=3 &&NOBLACK(i,j)) ADD(n,i,j)

i=x-1j=y-1if(i>=4 &&j>=1 &&NOBLACK(i,j)) ADD(n,i,j)

break

case 3:

case 4:

i=x+2j=y+2if(i<=9 &&j<=10 &&NORED(i,j)) if(NOMAN(x+1,y+1)) ADD(n,i,j)

i=x+2j=y-2if(i<=9 &&j>=6 &&NORED(i,j)) if(NOMAN(x+1,y-1)) ADD(n,i,j)

i=x-2j=y+2if(i>=1 &&j<=10 &&NORED(i,j)) if(NOMAN(x-1,y+1)) ADD(n,i,j)

i=x-2j=y-2if(i>=1 &&j>=6 &&NORED(i,j)) if(NOMAN(x-1,y-1)) ADD(n,i,j)

break

case 19:

case 20:

i=x+2j=y+2if(i<=9 &&j<=5 &&NOBLACK(i,j)) if(NOMAN(x+1,y+1)) ADD(n,i,j)

i=x+2j=y-2if(i<=9 &&j>=1 &&NOBLACK(i,j)) if(NOMAN(x+1,y-1)) ADD(n,i,j)

i=x-2j=y+2if(i>=1 &&j<=5 &&NOBLACK(i,j)) if(NOMAN(x-1,y+1)) ADD(n,i,j)

i=x-2j=y-2if(i>=1 &&j>=1 &&NOBLACK(i,j)) if(NOMAN(x-1,y-1)) ADD(n,i,j)

break

case 5:

case 6:

i=x+1

if(NOMAN(i,y))

{

i=x+2j=y+1if(i<=9 &&j<=10 &&NORED(i,j)) ADD(n,i,j)

i=x+2j=y-1if(i<=9 &&j>=1 &&NORED(i,j)) ADD(n,i,j)

}

i=x-1

if(NOMAN(i,y))

{

i=x-2j=y+1if(i>=1 &&j<=10 &&NORED(i,j)) ADD(n,i,j)

i=x-2j=y-1if(i>=1 &&j>=1 &&NORED(i,j)) ADD(n,i,j)

}

j=y+1

if(NOMAN(x,j))

{

i=x+1j=y+2if(i<=9 &&j<=10 &&NORED(i,j)) ADD(n,i,j)

i=x-1j=y+2if(i>=1 &&j<=10 &&NORED(i,j)) ADD(n,i,j)

}

j=y-1

if(NOMAN(x,j))

{

i=x+1j=y-2if(i<=9 &&j>=1 &&NORED(i,j)) ADD(n,i,j)

i=x-1j=y-2if(i>=1 &&j>=1 &&NORED(i,j)) ADD(n,i,j)

}

break

case 21:

case 22:

i=x+1

if(NOMAN(i,y))

{

i=x+2j=y+1if(i<=9 &&j<=10 &&NOBLACK(i,j)) ADD(n,i,j)

i=x+2j=y-1if(i<=9 &&j>=1 &&NOBLACK(i,j)) ADD(n,i,j)

}

i=x-1

if(NOMAN(i,y))

{

i=x-2j=y+1if(i>=1 &&j<=10 &&NOBLACK(i,j)) ADD(n,i,j)

i=x-2j=y-1if(i>=1 &&j>=1 &&NOBLACK(i,j)) ADD(n,i,j)

}

j=y+1

if(NOMAN(x,j))

{

i=x+1j=y+2if(i<=9 &&j<=10 &&NOBLACK(i,j)) ADD(n,i,j)

i=x-1j=y+2if(i>=1 &&j<=10 &&NOBLACK(i,j)) ADD(n,i,j)

}

j=y-1

if(NOMAN(x,j))

{

i=x+1j=y-2if(i<=9 &&j>=1 &&NOBLACK(i,j)) ADD(n,i,j)

i=x-1j=y-2if(i>=1 &&j>=1 &&NOBLACK(i,j)) ADD(n,i,j)

}

break

case 7:

case 8:

i=x+1

while(i<=9)

{

if (NOMAN(i,y)) ADD(n,i,y)

else

{

if(NORED(i,y)) ADD(n,i,y)

break

}

i++

}

i=x-1

while(i>=1)

{

if (NOMAN(i,y)) ADD(n,i,y)

else

{

if(NORED(i,y)) ADD(n,i,y)

break

}

i--

}

j=y+1

while(j<=10)

{

if (NOMAN(x,j)) ADD(n,x,j)

else

{

if(NORED(x,j)) ADD(n,x,j)

break

}

j++

}

j=y-1

while(j>=1)

{

if (NOMAN(x,j)) ADD(n,x,j)

else

{

if(NORED(x,j)) ADD(n,x,j)

break

}

j--

}

break

case 23:

case 24:

i=x+1

while(i<=9)

{

if (NOMAN(i,y)) ADD(n,i,y)

else

{

if(NOBLACK(i,y)) ADD(n,i,y)

break

}

i++

}

i=x-1

while(i>=1)

{

if (NOMAN(i,y)) ADD(n,i,y)

else

{

if(NOBLACK(i,y)) ADD(n,i,y)

break

}

i--

}

j=y+1

while(j<=10)

{

if (NOMAN(x,j)) ADD(n,x,j)

else

{

if(NOBLACK(x,j)) ADD(n,x,j)

break

}

j++

}

j=y-1

while(j>=1)

{

if (NOMAN(x,j)) ADD(n,x,j)

else

{

if(NOBLACK(x,j)) ADD(n,x,j)

break

}

j--

}

break

case 9:

case 10:

i=x+1flag=FALSE

while(i<=9)

{

if(NOMAN(i,y))

{

if(!flag) ADD(n,i,y)

}

else

{

if(!flag)flag=TRUE

else

{

if(NORED(i,y)) ADD(n,i,y)

break

}

}

i++

}

i=x-1flag=FALSE

while(i>=1)

{

if(NOMAN(i,y))

{

if(!flag) ADD(n,i,y)

}

else

{

if(!flag)flag=TRUE

else

{

if(NORED(i,y)) ADD(n,i,y)

break

}

}

i--

}

j=y+1flag=FALSE

while(j<=10)

{

if(NOMAN(x,j))

{

if(!flag) ADD(n,x,j)

【我是学c++的】呵呵,加了注释,你应该能明白一点^_^

1.10,void关键字

void有什么好讲的呢?如果你认为没有,那就没有;但如果你认为有,那就真的有。有点像“色即是空,空即是色”。

1.10.1,void a?

void的字面意思是“空类型”,void*则为“空类型指针”,void*可以指向任何类型的数据。void几乎只有“注释”和限制程序的作用,因为从来没有人会定义一个void变量,看看下面的例子:

voida

VisualC++6.0上,这行语句编译时会出错,提示“illegaluseoftype'void'”。不过,即使voida的编译不会出错,它也没有任何实际意义。

void真正发挥的作用在于:

(1) 对函数返回的限定;

(2) 对函数参数的限定。

众所周知,如果指针p1和p2的类型相同,那么我们可以直接在p1和p2间互相赋值;如果p1和p2指向不同的数据类型,则必须使用强制类型转换运算符把赋值运算符右边的指针类型转换为左边指针的类型。

例如:

float *p1

int *p2

p1=p2

其中p1=p2语句会编译出错,提示“'=':cannotconvertfrom'int*'to'float*'”,必须改为:

p1=(float*)p2

而void*则不同,任何类型的指针都可以直接赋值给它,团粗无需进行强制类型转换:

void *p1

int *p2

p1=p2

但这并不意味着,void*也可以无需强制类型转换地赋给其它类型的指针。因为“空类型”可以包容“有类型”,而“有类型”则不能包容“空类型”。比如,我们可以说“男人和女人都是人”,但不能说“人是男人”或者“人是女人”。下面的语句编译出错:

void *p1

int *p2

p2=p1

提示“'=':cannotconvertfrom'void*'to'int*'”。

1.10.2,void修饰函数返回值和参数

【规则1-33】如果函数没有返回值,那么应坦或辩声明为void类型

在C语言中,凡不加返回值类型限定的函数,就会被编译器作为返回整型值处理。但是许多程序员却误以为其为void类型。例如:

add(inta,intb)

{

return a+b

}

intmain(intargc,char*argv[])//甚至很多人以为main函数无返回值

//或是为void型的

{

printf("2+3=%d",add(2,3))

}

程序运行的结果为输出: 2+3=5

这说明不加返回值说明的函数的确为int函数。

因此,为了避免混乱,我们在编写C程序时,对于任何函数都必须一个不漏地指定其类型。如果函数没有返回值,一定要声明为void类型。这既是程序良好可读性的需要,也是编程规范性的要求。另外,加上void类型声明让缺后,也可以发挥代码的“自注释”作用。所谓的代码的“自注释”即代码能自己注释自己。

【规则1-34】如果函数无参数,那么应声明其参数为void

在C++语言中声明一个这样的函数:

intfunction(void)

{

return1

}

则进行下面的调用是不合法的:function(2)

因为在C++中,函数参数为void的意思是这个函数不接受任何参数。

但是在TurboC2.0中编译:

#include"stdio.h"

fun()

{

return1

}

main()

{

printf("%d",fun(2))

getchar()

}

编译正确且输出1,这说明,在C语言中,可以给无参数的函数传送任意类型的参数,但是在C++编译器中编译同样的代码则会出错。在C++中,不能向无参数的函数传送任何参数,出错提示“'fun':functiondoesnottake1parameters”。

所以,无论在C还是C++中,若函数不接受任何参数,一定要指明参数为void。1.10.3,void指针

【规则1-35】千万小心又小心使用void指针类型。

按照ANSI(AmericanNationalStandardsInstitute)标准,不能对void指针进行算法 *** 作,即下列 *** 作都是不合法的:

void*pvoid

pvoid++//ANSI:错误

pvoid+=1//ANSI:错误

ANSI标准之所以这样认定,是因为它坚持:进行算法 *** 作的指针必须是确定知道其指向数据类型大小的。也就是说必须知道内存目的地址的确切值。

例如:

int*pint

pint++//ANSI:正确

但是大名鼎鼎的GNU(GNU'sNotUnix的递归缩写)则不这么认定,它指定void*的算法 *** 作与char*一致。因此下列语句在GNU编译器中皆正确:

pvoid++//GNU:正确

pvoid+=1//GNU:正确

在实际的程序设计中,为符合ANSI标准,并提高程序的可移植性,我们可以这样编写实现同样功能的代码:

void*pvoid

(char*)pvoid++//ANSI:正确;GNU:正确

(char*)pvoid+=1//ANSI:错误;GNU:正确

GNU和ANSI还有一些区别,总体而言,GNU较ANSI更“开放”,提供了对更多语法的支持。但是我们在真实设计时,还是应该尽可能地符合ANSI标准。

【规则1-36】如果函数的参数可以是任意类型指针,那么应声明其参数为void*。

典型的如内存 *** 作函数memcpy和memset的函数原型分别为:

void*memcpy(void*dest,constvoid*src,size_tlen)

void*memset(void*buffer,intc,size_tnum)

这样,任何类型的指针都可以传入memcpy和memset中,这也真实地体现了内存 *** 作函数的意义,因为它 *** 作的对象仅仅是一片内存,而不论这片内存是什么类型。如果memcpy和memset的参数类型不是void*,而是char*,那才叫真的奇怪了!这样的memcpy和memset明显不是一个“纯粹的,脱离低级趣味的”函数!

下面的代码执行正确:

例子:memset接受任意类型指针

intIntArray_a[100]

memset(IntArray_a,0,100*sizeof(int))//将IntArray_a清0

例子:memcpy接受任意类型指针

intdestIntArray_a[100],srcintarray_a[100]

//将srcintarray_a拷贝给destIntArray_a

memcpy(destIntArray_a,srcintarray_a,100*sizeof(int))

有趣的是,memcpy和memset函数返回的也是void*类型,标准库函数的编写者都不是一般人。

1.10.4,void不能代表一个真实的变量

【规则1-37】void不能代表一个真实的变量。

因为定义变量时必须分配内存空间,定义void类型变量,编译器到底分配多大的内存呢。

下面代码都企图让void代表一个真实的变量,因此都是错误的代码:

voida//错误

function(voida)//错误

void体现了一种抽象,这个世界上的变量都是“有类型”的,譬如一个人不是男人就是女人(人妖不算)。

void的出现只是为了一种抽象的需要,如果你正确地理解了面向对象中“抽象基类”的概念,也很容易理解void数据类型。正如不能给抽象基类定义一个实例,我们也不能定义一个void(让我们类比的称void为“抽象数据类型”)变量。

void简单吧?到底是“色”还是“空”呢?

<<<<<<<<<<<<<,,,复制《C语言深度解剖》上的 >>>>>>>>>>>>>>>>>>>


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8267014.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存