8.2.3 二维数组

1.二维数组

我们前面讲的都是一维数组,也就是只有一个下标的数组,这个数组呢可以看成一个线性的东西.当然

除了一维数组,c语言也有二维数组,三维数组甚至n维数组.我们接下来看看二维数组怎么做.

做二维数组的时候,我们是这么定义的:如int a[3][5];这后面的方括号的个数就表明了这个数组的维数.我们通常理解是这个数组a是一个三行五列的矩阵,如果你一定说我要把它转过来,说它是三列五行的一个矩阵,如果你不去考虑这个数组在计算机的内存中是怎么排列的,那么从逻辑意义上来说,它反正就是那么一个矩阵,你拿第一个数字当行,你拿第二个数字当行都是一样的.但是在计算机内存中,那么我们倾向于把第一个数字作为行号,把第二个数字当作列号,所以我们在定义了这个数组,它在内存大概是这样放的:

这样子放呢,还有一个好处,就是正好和我们在线性代数中对这些东西的理解一样,在c语言和数学中都是这么理解,对于很多事情做起来可以顺很多.

那么对一个二维数组来说,我们要做的最重要的事情就是对它做遍历,也就是说和我们一维数组要做的事情一样.但是对于一维数组而言,因为只有一个下标,所以我们只需要一重循环就可以了,那么对于二维数组来说呢,我们就需要两重循环,外面遍历的那重是行号,里面遍历的这一重是列号.这样子才能完成对一个矩阵的遍历,对一个二维数组的遍历.如:

和一维数组一样,二维数组中的每一个元素的类型都是一样的.如我们上面定义好的整型数组a,a[i][j]就是一个整数,它表示的是在a中第i行第j列的单元.如果你把它写成a[i,j],它的意思是,a[j],这不是正确的表达二维数组的方式.

2.二维数组的初始化

二维数组也可以集成初始化.二维数组我们可以这样做来写:

行数是可以省略的,但是我们的列数是必须给出的,是不能省略的.由于这个数组是二维的,因此我们的大括号里面还得有大括号.事实上你可以把它想象成,说我们现在在定义什么呢,说我们现在有一个数组a,这数组里面的每一个呢,是一个五个的数组.所以这就顺理成章了,这个大括号表示的是有五个int的数组那么一个数组,它作为a[0],然后后面的是有五个int的数组,它作为a[1];同样的,如果你在集成初始化的时候有省略的,编译器会帮你补0.在c99里我们也可以用定位,但也得要用两个方括号的来做它的定位的初始化.

还有一种初始化的情况是,赋值号后面只有一个大括号.这也是可以的.因为如果你去看二维数组在计算机内存中的排列,它跟一维数组是一样的,所以你可以想象说,它会把这个矩阵(数组)从左上角到右下角用你的这些数字逐行的去填满.当然为了人类读者我们最好还是采取上面那种初始化方法.

3.tic-tac-toe游戏

我们来看一个二维数组的例子哈.大家都玩过这个游戏在中文我们叫做井字棋.就是我们有一个3*3的矩阵,在这上面你可以画oo或者划xx.如果有一方把它连成一条线了,他可能是横的,竖的,也可能是对角线,就表明他赢了.所以我们要做的事情很简单,我们并不是要去实现这个游戏,我们只是说如果我们的程序读到了这么一个矩阵,程序通过输入,从用户那边得到了这个矩阵,能不能判断出来现在的那个矩阵的情况,它的oo和xx的分布.是不是有一方赢了,如果有一方赢了,把那一方是oo还是xx输出来.或者说谁也没赢,怎么来做这样一个东西呢,这个程序其实非常简单(存疑),但是它刚好给我们演示了,在矩阵运算当中,在二维数组中,我们经常要去做的一些事情,比如说怎么去对一行进行遍历,怎么去对一列进行遍历.我们先来看读入矩阵的代码:

首先我们要去定义我们有这样的一个棋盘board,它的大小是size*size=8,然后我们想要去读入矩阵,就需要两个变量i和j;还有用于记录x和o的两个变量.通过这两重循环我们把整个矩阵读进来了,我们知道了棋盘上棋子的分布.

然后去检查行:

我们做的事情是说,我们去初始化记录o和x个数的两个变量为0,然后呢对应于i这一行,我们要去判断这一行的每一列,也就是这一行上的每一个数字,保持这个行号是不变的,然后列号从0走到size,如果它是xx的,那xx的变量+1,否则oo的变量+1.(我们默认棋盘是满的)算完以后看一下,如果oo的数量是3,那oo胜出,如果xx的数量为3,那么xx胜出.不然谁也没赢.

谁也没赢怎么办,继续去检查列:

列的算法和行的基本是一样的.变化在于循环的内层和外层,先走行还是先走列.这样的两段代码有没有可能合并起来呢?能否用一个两重循环来检查行和列?(目前我没去看,等后面写了再发出来)

最后检查对角线:

这是正对角线:

这是反对角线(省略了一部分代码):

这样子,做完这四遍检查,我们就可以知道棋盘上有没有谁赢了.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值