以前一直有种误解:
二维数组的是数组的数组,所以数组的首地址是指向第一个元素指针,而这个元素又是一个数组,所以把数组首地址理解为 指向指针的指针。
#include <stdlib.h>
int main(int argc, char **argv) {
int a[6][8];
int **p;
p = a;
return EXIT_SUCCESS;
}
因为a代表着除了第一列以外的列数的维数大小,如a+1的地址就是a[1]的地址,也就是a[1][0]的地址,而p仅是整形指针的指针,每跨越一次就是4字节,因此他们的大小是不匹配的,所以这样子直接等于号是不正确的。
要真正的定义方式应概是定义指向n维数组的指针,n就是除第一维的另外维度,
如上面的指针定义应该为
int (*p)[8]; p = a;
这样子就 可以就可以通过p以下标形式来访问数组。
测试1:
#include <stdio.h>
int main(int argc, char **argv) {
int gridArr[6][5] = {
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10},
{11, 12, 13, 14, 15},
{16, 17, 18, 19, 20},
{21, 22, 23, 24, 25},
{26, 27, 28, 29, 30}
};
int (*grid)[5]; // grid 为指向int的数组(元素个数为5)的指针
grid = gridArr;
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 5; j++) {
printf("%d\t", grid[i][j]);
}
printf("\n");
}
return 0;
}
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
测试2:
#include <stdio.h>
int main(int argc, char **argv) {
int gridArr[6][5] = {
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10},
{11, 12, 13, 14, 15},
{16, 17, 18, 19, 20},
{21, 22, 23, 24, 25},
{26, 27, 28, 29, 30}
};
int *grid[6]; // grid 为指向int的指针的数组(元素个数为6)
for (int i = 0; i < 6; i++) {
grid[i] = gridArr[i];
for (int j = 0; j < 5; j++) {
printf("%d\t", grid[i][j]);
}
printf("\n");
}
return 0;
}
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
测试3:使用 指向指针的指针
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int gridArr[6][5] = {
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10},
{11, 12, 13, 14, 15},
{16, 17, 18, 19, 20},
{21, 22, 23, 24, 25},
{26, 27, 28, 29, 30}
};
int i, j;
int **grid = (int **) malloc(6 * sizeof(int *)); // 注意:是两个**
for (i = 0; i < 6; i++) {
grid[i] = (int *) malloc(5 * sizeof(int *)); // 注意:是一个*
for (j = 0; j < 5; j++) {
// 方式一:下标引用
grid[i][j] = gridArr[i][j];
// 方式二:指针计算
// *(*(grid + i) + j) = gridArr[i][j];
}
}
for (i = 0; i < 6; i++) {
for (j = 0; j < 5; j++) {
// 方式一:下标引用
printf("%d\t", grid[i][j]);
// 方式二:指针计算
// printf("%d\t", *(*(grid + i) + j));
}
printf("\n");
}
return 0;
}
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
参考: