文章目录
- 1. 二维数组
- 1.1 二维数组的创建和初始化
- 1.1.1 完全初始化
- 1.1.2 不完全初始化
- 1.1.3 按照行初始化
- 1.2 二维数组的使用
- 1.3 二维数组的内存中的存储
- 2.变长数组
1. 二维数组
前面学习的数组被称为一维数组,数组的元素都是内置类型的,如果把一维数组作为另一个数组的元素,就构成了二维数组,以二维数组为元素的数组则称为三维数组,二维数组以上的数组统称为多维数组。
1.1 二维数组的创建和初始化
定义:
type arr_name[常量值1][常量值2];例如,下面这条语句创建了一个 3 行 4 列的整型二维数组:
intarr[3][4];它表示数组共有 3 行,每行有 4 个元素,总共有 12 个元素。
1.1.1 完全初始化
inta[3][5]={{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}};1.1.2 不完全初始化
inta[3][5]={{1,2}};1.1.3 按照行初始化
intarr4[3][5]={{1,2},{3,4},{5,6}};重点:
初始化时省略行,但是不能省略列
1.2 二维数组的使用
二维数组的元素通过「行下标 + 列下标」来访问,下标同样从 0 开始。
intarr[3][5]={1,2,3,4,5,2,3,4,5,6,3,4,5,6,7};在实际开发中,二维数组最常配合双重循环来遍历。下面是一个完整的示例,它创建一个 3 行 4 列的数组,逐行逐列赋值并打印:
intmain(){intarr[3][4];inti,j;// 逐行逐列赋值for(i=0;i<3;i++){for(j=0;j<4;j++){arr[i][j]=i*4+j+1;}}// 逐行逐列打印for(i=0;i<3;i++){for(j=0;j<4;j++){printf("%4d ",arr[i][j]);}printf("\n");// 每打印完一行换行}return0;}运行结果如下:
1 2 3 4 5 6 7 8 9 10 11 12这就是二维数组的输入和输出
外层循环控制行号,内层循环控制列号,这种「外层行、内层列」的遍历顺序是二维数组最常用的访问方式。
1.3 二维数组的内存中的存储
虽然二维数组在逻辑上呈现为「行和列」的二维结构,但在内存中,它实际上是连续存储的。C 语言采用「行优先」的存储方式,即先依次存放第一行的所有元素,再存放第二行的所有元素,以此类推。
以int arr[3][4]为例,它在内存中的排列顺序为:
#include<stdio.h>intmain(){intarr[3][5]={0};inti=0;intj=0;for(i=0;i<3;i++){for(j=0;j<5;j++){printf("&arr[%d][%d] = %p\n",i,j,&arr[i][j]);}}return0;}打印结果如图:
由图来看,同一行内的相邻元素地址连续,地址之间相差 4 个字节,跨行位置处的两个元素(如:arr[0][4] 和 arr[1][0])之间也相差 4 个字节,所以二维数组中的每个元素都是连续存放的——这是非常关键的。
2.变长数组
变长数组(Variable Length Array,VLA)是 C99 标准引入的一个特性,它允许在定义数组时使用变量来指定数组的长度,而不是像传统数组那样必须使用编译期常量。
但是在 VS 上目前还不能使用,需要切换到 Clang 编译器才能使用。
下面我们在 Clang 下写一段代码。在运行时根据用户输入的行数和列数创建二维数组:
#include<stdio.h>intmain(){introws,cols;printf("请输入行数和列数:");scanf("%d %d",&rows,&cols);intmatrix[rows][cols];// 变长二维数组// 使用双重循环填充并打印for(inti=0;i<rows;i++){for(intj=0;j<cols;j++){matrix[i][j]=i*cols+j;printf("%4d ",matrix[i][j]);}printf("\n");}return0;}变长数组的长度是在程序运行时才确定的,因此它不能像普通数组那样在定义时进行初始化,也不能是全局变量或静态变量。