1、二维数组的定义
定义形式:类型说明符 数组名[常量表达式1][常量表达式2] ;
类型说明符:数组的类型;
数组名:遵循标志符的命名规则;
其中常量表达式1表示行数,常量表达式2 表示列数。
例如: float a[3][4];
表示: a为3行4列的二维实型数组,共包含12个数组元素。
a[0][0] , a[0][1], a[0][2] , a[0][3] 第一行的4个元素
a[1][0] , a[1][1], a[1][2] , a[1][3]
a[2][0] , a[2][1] , a[2][2] , a[2][3]
注意:
1)两个下标要分别用中括号括起来。不能写成float a[3,4];
2)常量表达式只能是常量,不能是变量。int b[m][n];
2、数组元素的引用
引用二维数组元素的形式为:数组名[下标][下标]
下标可以是整型常量或整型表达式。
在使用数组元素时,下标应在定义的范围内。
常出现的错误如下:
int a[3][4];
a[3][4]=3;
3、二维数组的初始化
可在定义数组的同时对二维数组元素进行初始化,形式:
数据类型 数组名 [常量1][常量2]={初始化数据};
也可以给全部数组元素赋初值,或给部分元素赋初值。
如果是给全部数组元素赋初值,两种形式:
1)分行赋初值。如:
inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
2)不分行,也就是将所有数据放在一个大括号内。如:
inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
注意:对全部元素赋初值时,第一维的长度可以不指定,但第二维的长度不能省。
也可对部分元素赋初值:
inta[3][4]={ {1},{5},{9} };
对每一行第一列的元素赋初值,其他元素为0;
4、数组元素在内存中的存放
int a[3][3]={ {1,2,3}, {4,5,6}, {7,8,9} };
定义a为3行3列的整型数组,共包含9个数组元素,每个数组元素占4个字节,给a数组共分配36个字节,在内存中按行存放,首先存放第一行的3个数组元素的值,然后存放第二行的3个数组元素的值……。
5、二维数组的应用
1)输出各数组元素
inta[3][3]={{1,2,3},{4,5,6},{7,8,9}};
int i,j; 用i控制行数,j控制列数
for(i=0;i<3;i++)
{ for(j=0;j<3;j++)
printf(“%4d”,a[i][j]); 引用数组元素,每输出4个数换行
printf(“\n”);}
分析程序段结果:
for(i=0;i<3;i++)
for(j=0;j<3;j++)
printf("%4d",a[j][i]); 引用数组元素,j控制行号,i控制列号
思考: 如何输出上三角矩阵?
2)已知4个学生3门课的成绩,求:每个学生的平均分?每门课程的平均分?
首先定义数组:
{ float a[4][3]={{80,75,68},{78,90,83},{55,64,68},{60,72,76}};
int i,j; 用i控制学生人数,j控制课程数
i=0,表示第一个学生,i从0-3变化
j=0,表示第一门课程,j从0-2变化
先求每个学生的平均分。要求每个学生的平均分,首先要求出每个学生的总分再除3;总分用sum来存放,定义sum:
float sum=0;
for(i=0;i<4;i++) i控制学生人数,共4个学生
{ sum=0; 不给出该语句,结果出错
for(j=0;j<3;j++) 每个学生有3门成绩
sum=sum+a[i][j];
printf("%.1f\n",sum/3);} 计算第二个学生的总分时,把第一个学生的总分也加入
求每门课程的平均分:
有3门课程,每门课程有4个成绩,先从第一门课程开始,将4个成绩相加后,除以4就得到该课程的平均分,然后再求第二门课程……,一共3列,所以外层循环控制列号
for(j=0;j<3;j++) j控制课程数,3门课程
{ sum=0;
for(i=0;i<4;i++) i控制学生人数,共4个学生
sum=sum+a[i][j];
printf("%d :%.1f\n",j+1,sum/4);
}
总结:对于有行有列的数据,如表格、矩阵是用二维数组来存放。对某个学生的某个成绩,用a[i][j]的形式,可以很直观地就知道代表的是第i+1个学生的j+1门课程的成绩。
思考题:输出杨辉三角的前6行数据。
1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 5 1 |
规律:
(1)各行第一个数都是1;
(2)各行最后一个数都是1;
(3)其余各数是上一行同列和前一列两个数之和。
*EASY图形编程.二维数组的应用
程序要求:屏幕上有 16x8 的方格,按随机顺序在将 1~128 的数字写到每个格子上。
考虑:我们需要记录这些格子,哪些写过数字,哪些没写数字。
我们用一个二维数组来记录:
bool cell[16][8];
写过数字后,我们将相应数组的值设置为 true,看程序:
#include <graphics.h>
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#include <time.h>
void main()
{
int x, y;
char num[4];
srand( (unsigned)time(NULL) );
initgraph(640, 480);
// 画格子
for (x=0; x<=480; x+=30)
for (y=0; y<=240; y+=30)
{
line(x, 0,x, 240);
line(0, y,480, y);
}
getch();
// 定义二维数组
bool cell[16][8];
// 初始化二维数组
for (x=0; x<16; x++)
for (y=0; y<8; y++)
cell[x][y] =false;
// 在每个格子上写数字
for (int i=1; i<=128; i++)
{
// 找到一个没有写数字的随机格子
do
{
x = rand() %16;
y = rand() %8;
}while(cell[x][y] == true);
// 标记该格子已用
cell[x][y] = true;
// 在格子上写数字
sprintf(num, "%d", i);
outtextxy(x * 30+5, y * 30+10, num);
}
getch();
closegraph();
}
以上几个范例,无论从实用上还是美观上都很差,我只是希望大家能举一反三,写出更多漂亮的程序。
[作业]
1. 回顾一下上一节课的作业,绘制一个任意反弹的球。这次,将程序修改成屏幕上有 10 个任意反弹的球。
2. 如果反弹的不是球,而是点呢?再将某些点之间用线连起来,就可以做一个屏保“变幻线”的程序了。试试做一个。
3. 写“涂格子(也叫点灯)”的游戏。详细规则可以试玩网上的各种版本。
以下作业,有时间就写。因为讲完这 12 节课,可以写出很多游戏了,所以可能会感觉作业一下子多了许多。
4. 写个俄罗斯方块。

