如何用二级指针访问a[m][n]二维数组?为何int**b=num无法访问
二级指针访问二维数组的问题解析
问题根源:二维数组与二级指针的类型差异
错误代码里的int **b = num;本质是类型不匹配:
- 二维数组
num[3][4]的类型是int (*)[4](指向包含4个int元素的一维数组的指针),它指向数组首行,内存中是连续存储的整块数据:1,2,3,4,5,6,7,8,9,10,11,12。 - 而
int**是指向int*类型的指针,它要求指向的内存里存储的是另一个int指针的地址,和二维数组的内存布局完全不兼容。
执行*(*(b+1)+2)时:
b+1会按int**的大小(通常8字节)偏移,而非二维数组每行的16字节(4个int×4字节),直接指向错误内存位置。- 解引用该错误地址时,会把内存中的随机值当作
int*指针,再次解引用就触发了段错误。
不修改int **b = num;的前提下访问数组
既然不能修改赋值语句,就得绕过类型不匹配问题,手动计算二维数组的内存偏移——因为二维数组是连续存储的,num[i][j]的实际内存位置等价于*( (int*)num + i*4 + j ),我们可以把b强制转换为int*类型来计算偏移:
#include <stdio.h> #include <stdlib.h> int main() { int num[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}; int **b = num; // 访问num[1][2],计算偏移量:1行×4列 + 2列 printf("num[1][2] = %d\n", *( (int*)b + 1*4 + 2 )); // 输出7 // 其他示例 printf("num[0][0] = %d\n", *( (int*)b )); // 输出1 printf("num[2][3] = %d\n", *( (int*)b + 2*4 +3 )); // 输出12 }
补充:推荐的正确写法
上述方法是绕过类型检查的权宜之计,实际开发中应该使用匹配的指针类型,避免类型不匹配问题:
#include <stdio.h> #include <stdlib.h> int main() { int num[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}}; int (*b)[4] = num; // 定义指向含4个int元素的数组的指针 printf("num[1][2] = %d\n", *(*(b+1)+2)); // 正常输出7 }
内容的提问来源于stack exchange,提问作者Eric的小弟
相关产品推荐
相关产品推荐

