1、二维数组
每一个元素是类型相同、长度相等的一维数组。
2、定义二维数组
类型 数组名 [常量表达式]...[常量表达式]
例子:
int a[3][4]; // 二维数组,3行4列
double b[2][3][2]; // 三维数组,2 * 3 * 2 = 12 个元素
int i[2][3] = { {1, 2, 3}, {4, 5, 6} }; // 数组初始化
int j[2][3] = {1, 2, 3, 4, 5, 6}; // 与 i 数组初始化方式等价
int k[][2][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; // 缺省第一维长度
int l[][4] = { {1}, {1}, {1} } ; // 仅对第 0 列元素赋初值
int m[3][] = {1, 2, 3, 4, 5, 6} // 错误,不能省略第二维长度
3、对于一位数组a[5]
- a[ ]等价于*a
- 数组名代表数组的首地址
- 任一数组元素的地址,可以用数组名加偏移量表示
例子:
地址值 | 元素值 |
a <--> &a[ 0 ] | a [ 0 ] <--> *a |
a+1 <--> &a[ 1 ] | a [ 1 ] <--> *(a+1) |
a+2 <--> &a[ 2 ] | a [ 2 ] <--> *(a+2) |
.. | .. |
a+i <--> &a[ i ] | a [ i ] <--> *(a+i) |
二维数组的每一个元素是同构的一维数组
4、以指针方式访问二维数组
二维数组名是逻辑上的一个二级指针,
是一级指针
用二维数组名引用基本类型时,应该是二级引用,但不能直接把二维数组名赋给二级指针变量,因为不管 n 维数组,数组名仅是内存块首地址
int a[3][5], **p2, *p1;
p1 = *a; // OK
p1 = a[0]; // OK,a[0]表示取第0行元素的首地址
p1 = a; // Error
p2 = a; // Error,不能将 int (*)[5] 类型的值赋给 int ** 类型的实体
a的类型为int (*)[5],是逻辑上的二级指针
*a的类型为int *
&a的类型为 int (*)[3][5]
a[0]的类型为int *,即 *a == a[0],第0行元素的首地址
a[0]表示第0行第0列元素的地址
第0行第1列元素的地址 | a[0]+1 | *a+1 | &a[0][1] |
第1行第2列元素的地址 | a[1]+2 | *(a+1)+2 | &a[1][2] |
第i行第j列元素的地址 | a[i]+j | *(a+i)+j | &a[i][j] |
第1行第2列元素的值 | *(a[1]+2) | *(*(a+1)+2) | *(&a[1][2])-->a[1][2] |
第i行第j列元素的值 | *(a[i]+j) | *(*(a+i)+j) | *(&a[i][j])-->a[i][j] |