C 二维数组简介
之前我们介绍的都是一维数组,在实际开发中,数组很多时候是二维甚至更多维的,不过更常见的还是二维数组。
一维数组只有 1 个下标,二维数组有 2 个下标。当然了,n 维数组就肯定有 n 个下标。下面我们来学习一下二维数组。
在 C 语言中,如果想要定义一个二维数组,一般有 4 种方式。比如我们定义一个 2 行 3 列的二维数组,其实现方式如下。
// 方式 1
int arr[2][3] = {{10, 20, 30}, {40, 50, 60}};
// 方式 2
int arr[2][3] = {10, 20, 30, 40, 50, 60};
// 方式 3
int arr[][3] = {10, 20, 30, 40, 50, 60};
// 方式 4
int arr[2][3];
arr[0][0] = 10;
arr[0][1] = 20;
arr[0][2] = 30;
arr[1][0] = 40;
arr[1][1] = 50;
arr[1][2] = 60;方式 1 和方式 4 比较容易理解,我们没有什么问题。对于方式 2,因为二维数组在内存中是按照 “线性顺序” 来存储的,所以编译器会根据 “数组的行数或列数” 以及 “右边元素的个数”,自动对右边元素进行划分。
在 C 语言中,二维数组是按行优先的顺序存储的,即先存储完第一行的所有元素,再存储第二行的所有元素,以此类推。但在实际开发中,我们更推荐使用方式 1,因为它更加直观,代码的可读性更高。
对于方式 3,当我们省略第一维的大小(行数)时,必须指定第二维的大小(列数)。编译器会根据指定的列数和初始化列表中元素的总数来自动计算出行数。在上面代码中,总共有 6 个元素,每行 3 个,所以编译器会推断出数组有 2 行。
实际上,二维数组可以看作是由一维数组嵌套而成的。对于二维数组来说,它的每一个元素本身又是一个一维数组。这一点从方式 1 就可以很直观地看出来了。
C 二维数组的应用
接下来,我们通过几个简单例子来讲解一下 C 二维数组是如何使用的。
示例 1:计算二维数组所有元素之和
#include <stdio.h>
int main(void)
{
int arr[3][4] = {{2, 4, 6, 8}, {10, 12, 14, 16}, {18, 20, 22, 24}};
int sum = 0;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
sum += arr[i][j];
};
}
printf("%d", sum);
return 0;
}运行结果如下。
156分析:
对于一维数组来说,我们只需要用 1 层 for 循环 就可以遍历完。但是对于二维数组来说,需要 2 层 for 循环才能遍历完。第 1 层用于控制 “行数” 的变化,第 2 层用于控制 “列数” 的变化。对于多维数组来说,有多少维,就应该使用多少层 for 循环。
当然了,我们也可以使用 for 循环来快速创建一个二维数组,请看下面例子。
示例 2:输出二维数组的元素
#include <stdio.h>
int main(void)
{
int arr[3][4];
int count = 1;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
arr[i][j] = count * 2;
count++;
}
}
printf("%d\n", arr[0][0]);
printf("%d\n", arr[0][1]);
printf("%d", arr[0][2]);
return 0;
}运行结果如下。
2
4
6分析:
上面这个例子用于创建一个 3 行 4 列的二维数组,该二维数组最终值为:{{2, 4, 6, 8}, {10, 12, 14, 16}, {18, 20, 22, 24}}。
在 C 语言中,数组的元素在内存是连续存放的,并且是 “按行优先” 进行存储的。比如整型数组 arr[3][4],先存放 arr[0] 行,然后存放 arr[1] 行,最后存放 arr[2] 行。对于每一行中的元素也是依次存放的。
因为每一个 int 类型占据 4 个字节的内存大小,对于 arr[3][4] 这个数组来说,总共占据了 4 × 3 × 4 = 48 个字节大小。
