以前一直有种误解:
二维数组的是数组的数组,所以数组的首地址是指向第一个元素指针,而这个元素又是一个数组,所以把数组首地址理解为 指向指针的指针。
#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
参考: