1、二维数组的定义和使用:
(1)定义形式:
类型名 数组名 [行长度][列长度];
类型名:数组中每个元素的类型;
数组名:数组变量(数组)的名称;
行长度和列长度:整型常量表达式,分别给定数组的行数和列数;
例如:int a[3][2]//定义一个二维数组,3行2列,共3*2=6个元素
(2)引用:
二维数组的引用要指定两个下标,即行下标和列下标,形式为:
数组名 [行下标][列下标]
如:a[0][1]
注意下标不要越界!
!!!行长度的合理取值范围为:[0,行长度-1]!!!
!!!列长度的合理取值范围为:[0,列长度-1]!!!
二维数组的元素按先行后列的形式顺序存放。
2、二维数组的初始化:
(1)分行赋初值:
一般形式为:
类型名 数组名 [行长度][列长度] = {{初值表0},……{初值表k},……};
如:int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; 初始化数组a。
此时,a数组中各元素为:
1 2 3
4 5 6
7 8 9
二维数组的初始化也可以只针对部分元素:
static int b[4][3] = {{1,2,3},{ },{4,5}}
//只对b数组第0行全部元素赋初值和第二行的前两个元素赋初值,其余元素初值都是0.
(2)顺序赋初值:
一般形式为:
类型名 数组名[行长度][列长度] = {初值表};
如:int a[3][3] = {1,2,3,4,5,6,7,8,9};
即等价于:int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
注意:
如果只对部分元素赋初值,要注意初值表中数据的书写顺序。
如:static int b[4][3] = {1,2,3,0,0,0,4,5};
等价于:static int b[4][3] = {{1,2,3},{ },{4,5}};
如在初值表中列出了全部行,就可以省略行长度。
如:static int b[4][3] = {1,2,3,4,5,6,7,8,9};
等价于:static int b[ ][3] = {1,2,3,4,5,6,7,8,9};
不过建议不要省略行长度!!!
4、使用二维数组编程:
讲行下标和列下标分别作为循环变量,通过二重循环,就可以遍历二维数组。
一般把行下标作为外循环的循环变量,列下标作为内循环的循环变量,可以提高程序执行效率!
编程如下:
for(j=0;j<n;j++){
for(i=0;i<m;i++){
scanf("%d",&a[i][j]);
}
}
矩阵的术语于二维数组下标的对应关系
术语 | 含义 | 下标规律 |
主对角线 | 从矩阵的左上角至右下角的连线 | i == j |
上三角 | 主对角线以上的部分 | i <= j |
下三角 | 主对角线以下的部分 | i >= j |
副对角线 | 从矩阵的右上角至左下角的连线 | i + j == N - 1 |
例:求矩阵的最大值。输入两个正整数m和n(1<=m,n<=6),再输入1个m*n的矩阵,找出
最大值及它的行下标和列下标。假设最大值唯一。
#include <stdio.h>
//以下为宏定义,方便使用
#define MAXN 6
#define MAXM 6
int main(void)
{
int i,j,m,n;
int a[MAXN][MAXM];
int row,col;//row为行下标,col为列下标
scanf("%d %d",&m,&n);
//行下标作为外循环
for(i = 0;i < m;i++){
//列下标作为内循环
for(j = 0;j < n;j++){
scanf("%d",&a[i][j]);
}
}
//输入完毕!
//以下为寻找最大值及其行下标和列下标
row = 0;
col = 0;
for(i = 0;i < m;i++){
for(j = 0;j < n;j++){
if(a[row][col] < a[i][j]){
row = i;
col = j;
}
}
}
//寻找完毕
//以下为输出最大值及其行下标和列下标
printf("max = a[%d][%d] = %d\n",i,j,a[row][col]);
return 0;
}
从中的启发:
1)宏定义前要有“#”,不然无定义
2)行下标作为外循环,列下标作为内循环
3)具体步骤与一维数组操作一致
练习:方阵转置。输入一个正整数n(1<=n<=6),根据下式生成一个n*n的方阵,将该方阵转置(行列互换)后输出。
1 2 3
4 5 6
7 8 9
1 4 7
2 5 8
3 6 9
我的编程如下:
#include <stdio.h>
#define MAXN 6
#define MAXM 6
int main(void)
{
int i,j,n,count = 0,temp;
int a[MAXN][MAXM];
scanf("%d",&n);
for(i = 0;i < n;i++){
for(j = 0;j < n;j++){
scanf("%d",&a[i][j]);
}
}
//输入完毕
//以下对矩阵转置输出
for(i = 0;i < n;i++){
for(j = 0;j < n;j++){
temp = a[i][j];
a[i][j] = a[j][i];
a[j][i] = temp;
}
}
//转换完毕
//以下对转换后的矩阵进行输出
for(j = 0;j < n;j++){
for(i = 0;i < n;i++){
printf("%d ",a[i][j]);
count++;
if(count >= n&&count % n == 0){
printf("\n");
}
}
}
return 0;
}
书本编程如下:
#include <stdio.h>
#define MAXN 6
#define MAXM 6
int main(void)
{
int i,j,n,count = 0,temp;
int a[MAXN][MAXM];
scanf("%d",&n);
for(i = 0;i < n;i++){
for(j = 0;j < n;j++){
scanf("%d",&a[i][j]);
}
}
//输入完毕
//以下对矩阵转置输出
for(i = 0;i < n;i++){
for(j = 0;j < n;j++){
//以下遍历上三角阵
if(i <= j){
temp = a[i][j];
a[i][j] = a[j][i];
a[j][i] = temp;
}
}
}
//转换完毕
//以下对转换后的矩阵进行输出
for(i = 0;i < n;i++){
for(j = 0;j < n;j++){
printf("%d ",a[i][j]);
count++;
if(count >= n&&count % n == 0){
printf("\n");
}
}
}
return 0;
}
两者的区别为:
1)书本中的编程只遍历上三角阵,我的编程遍历全部元素
2)书本中输出时与输入时一致,都是把行下标在外,列下标在内,而我的编程是行下标在内,列下标在外
输出结果都为:
只遍历上三角阵的代码有两种:
for(i = 0;i < n;i++){
for(j = 0;j < n;j++){
if(j <= j){
...
}
}
}
for(i = 0;i < n;i++){
for(j = i;j < n;j++){
...
}
}
听课后的启示:
如果遍历所有元素,相当于转置后的元素又转置回来了,等同于无遍历,因此此段代码没有意义!!!
对于n*n的方阵来说,直接行坐标与列坐标颠倒输出即为n*n的方阵倒置!!!
但此种方法对于不是n*n的方阵来说方阵倒置不管用!!!
应改为遍历上三角阵或者下三角阵(如书本代码所示,如上图)!!!
练习:
计算天数。定义函数day_of_year(year,month,day),计算并返回年year、月month和日day对应的是该年的第几天。
编程如下:
我写的:
#include <stdio.h>
int day_of_year(int year,int month,int day);
int main(void)
{
int year,month,day;
scanf("%d %d %d",&year,&month,&day);
printf("%d",day_of_year(year,month,day));
return 0;
}
int day_of_year(int year,int month,int day)
{
int k,leap,sum = 0;
//以下定义二维数组
int a[2][13] = {
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
//定义完毕
//以下判断是否为闰年
if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
leap = 1;
}else{
leap = 0;
}
//判断完毕
if(leap == 1){
k = month;
for(k = 1;k < month;k++){
sum = sum + a[leap][k];
}
sum = sum + day;
}else{
k = month;
for(k = 1;k < month;k++){
sum = sum + a[leap][k];
}
sum = sum + day;
}
return sum;
}
简化后的:
#include <stdio.h>
int day_of_year(int year,int month,int day);
int main(void)
{
int year,month,day;
scanf("%d %d %d",&year,&month,&day);
printf("%d",day_of_year(year,month,day));
return 0;
}
int day_of_year(int year,int month,int day)
{
int k,leap;
//以下定义二维数组
int a[2][13] = {
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
//定义完毕
//以下判断是否为闰年
if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){
leap = 1;
}else{
leap = 0;
}
//判断完毕
//以下计算天数
for(k = 1;k < month;k++){
day = day + a[leap][k];
}
return day;
}

运行如下: