对于二维数组 array[4][5]
. array
应理解为是包含四个元素的数组,每个元素是一个一维数组,它们有五个元素。
例:
int mat[3][4];
![a9962f4a4bb85f9029c80df8219f1a04.png](https://i-blog.csdnimg.cn/blog_migrate/3b5546967fccf2dec7d8581a7b4b08c2.png)
数组含义:
- 数组
mat
包含三个元素:mat[0]
,mat[1]
,mat[2]
mat
的第一个元素mat[0]
是包含四个整形变量的数组
考虑到数组名代表数组第一个元素的地址
mat
是其第一个元素mat[0]
的地址,即mat = &mat[0]
mat[0]
是其第一个元素mat[0][0]
的地址,即mat[0] = &mat[0][0]
*mat = mat[0]
, 于是*mat
指mat[0][0]
的地址
因为mat[0]
和 mat[0][0]
的地址都是数组的起始位置,地址相同,所以:
mat = &mat[0] = mat[0] = &mat[0][0] = *mat
mat + 1
指向数组mat
的第二个元素,是mat[1]
的地址-
mat + 1 = &mat[1]
-
mat[0] + 1
指向数组mat[0]
的第二个元素,是mat[0][1]
的地址-
mat[0] + 1 = &mat[0][1]
-
![32fa379e2bc90ed6ae00ad3a8bae339b.png](https://i-blog.csdnimg.cn/blog_migrate/5804e519ef3dd801ac3e884e240b0f15.jpeg)
程序示例
#include <stdio.h>
int main()
{
int array[4][5] = {0};
printf("sizeof int : %dn", sizeof(int));
printf("array : %pn", array);
printf("array + 1 : %pn", array + 1);
return 0;
}
/*--------OUTPUT--------*/
sizeof int : 4
array : 0x7ffee9ee0a60
array + 1 : 0x7ffee9ee0a74 // 跨越了五个元素
下面考虑解引用和指针的运算
- 前面已经提到对二级指针
mat
的解引用*mat
是mat[0]
- 对一级指针
mat[0]
的解引用*mat[0]
是mat[0][0]
![d36b5976202a287b969fa620aac6c485.png](https://i-blog.csdnimg.cn/blog_migrate/e6de0a83b0cb3e04779b93aaf29ed75d.jpeg)
![3bbc286967de69f24e296683688319bc.png](https://i-blog.csdnimg.cn/blog_migrate/1f565d2dc30136663d48700668bcef68.jpeg)
即:
// 一层解引用:
*mat = mat[0] = &mat[0][0]
*mat[0] = mat[0][0]
*(mat+1) = mat[1] = &mat[1][0]
*mat[1] = mat[1][0]
// 二层解引用:
**mat = *mat[0] = mat[0][0]
**(mat+1) = *(mat[1]) = mat[1][0]
*(*(mat+1)+1) = *(mat[1]+1) = mat[1][1]
// 总结:
*(array+i) == array[i]
*(*(array+i)+j) == array[i][j]
*(*(*(array+i)+j)+k) == array[i][j][k]
程序实例
#include <stdio.h>
int main()
{
int array[4][5] = {0};
int i, j, k = 0;
for (i = 0; i < 4; i++){
for (j = 0; j < 5; j++){
array[i][j] = k++;
}
}
printf("*(array + 1): %pn", *(array + 1));
printf("array[1]: %pn", array[1]);
printf("&array[1][0]: %pn", &array[1][0]);
printf("**(array + 1): %dn", **(array + 1));
return 0;
}
/*--------OUTPUT--------*/
*(array + 1): 0x7ffee924aa74
array[1]: 0x7ffee924aa74
&array[1][0]: 0x7ffee924aa74
**(array + 1): 5
行指针和列指针
int a[3][4];
a
,a+1
分别指向第一行,第二行的一维数组, 称为行指针a+1 = &a[1]
- 解引用行指针得到一维数组
a[0] = *(a+0)
,a[0]+1 = *(a+1)
分别指向第一行第一列,第一行第二列元素的地址,称为列指针(元素指针)a[i] = &a[i][0]
,a[i]+j = &a[i][j]
- 解引用列指针得到一维数组内的元素
*(a[i]+j) = a[i][j]
- 行指针解引用后是列指针
*a = a[0]
*(a+i) = a[i] = &a[i][0]
数组指针和二维数组
#include <stdio.h>
int main()
{
int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
int *p;
p = *a; // p 是列指针/一级指针,指向第一行第一列
// p = &a[0][0]; (对),也是第一行第一列的地址
// p = a; (错), a是行指针/二级指针
for(p=a[0]; p < a[0] + 12; p++)
{
if((p - a[0]) % 4 == 0)
printf("n");
printf("%4d ", *p); // 解引用得到元素
}
return 0;
}
这是普通指针,下面使用数组指针。数组指针指向一个一维数组,解引用数组指针得到数组。
#include <stdio.h>
int main()
{
int array[2][3] = {{0, 1, 2},
{3, 4, 5}};
int (*p)[3] = array;
// 一层解引用
printf("*p: %pn", *p); // 0x7ffee2b20aa0
printf("p[0]:%pn", p[0]); // 0x7ffee2b20aa0
printf("*p+1:%pn", *p+1); // 0x7ffee2b20aa4
printf("*(p+1):%pn", *(p+1)); // 0x7ffee2b20aac
// 二层解引用
printf("**p:%dn", **p); // 0
printf("*p[0]:%dn", *p[0]); // 0
printf("*(*p+1):%dn", *(*p+1)); // 1
printf("**(p+1):%dn", **(p+1)); // 3
printf("*p[1]:%dn", *p[1]); // 3
printf("**(array+1):%dn", **(array + 1)); // 3
printf("array[1][0]:%dn", array[1][0]); // 3
printf("*(*(p+1)+1):%dn", *(*(p+1)+1)); // 4
return 0;
}
这里p
指向array
的第一行,即四个元素的一维数组(因为这就是array
储存的地址信息) p
的跨度是 3个int
,于是
*p
得到array
的第一行一维数组,*p
是第一行第一个元素的地址**p
得到第一行第一个元素
- 将
*p
看作一个一维数组p[0]
,跨度为int
+(*p+1) = p[0]+1
得到第一行第二个元素的地址*(*p+1) = *(p[0]+1)
得到第一行第二个元素
p+1
指向 array
的第二行
*(p+1)
得到数组的第二行一维数组,*(p+1)
是第二行第一个元素的地址**(p+1)
得到第二行的第一个元素
- 将
*(p+1)
看作一个一维数组p[1]
,跨度为int
*(p+1)+1 = p[1]+1
得到第二行第二个元素的地址*(*(p+1)+1) = *(p[1]+1)
得到第二行第二个元素
![36052493f00a2fa4414319b27407efa0.png](https://i-blog.csdnimg.cn/blog_migrate/32bd36cb867e860cffc4eaeeb2ad5a54.jpeg)
int (*p)[3] = array+1 // 指向array的第二行
还可以这样写:
#include <stdio.h>
int main()
{
int array[2][3] = {{0, 1, 2},
{3, 4, 5}};
int (*p)[2][3] = &array;
int i,j;
for ( i = 0; i < 2; ++i) {
for ( j = 0; j < 3; ++j) {
printf("%2d ", *(*(*p+i)+j));
}
printf("n");
}
return 0;
}
这里p
指向这个二维数组,先解引用*p
得到array
,后面就是一样的了。