C语言中*(*(*p)))指针是什么?如何用p3取出三维数组中的5?
三维数组与指针的解析
一、*(*(*(p3))+4) 取5的原理拆解
先明确变量类型和内存布局:
dat是int[2][3][2]类型的三维数组,内存中连续存储,顺序为:1,2,3,4,5,6,7,8,9,19,11,12p3的类型是(*)[3][2],即指向3×2二维数组的指针,它指向dat的第一个元素(也就是dat[0],这个元素本身是一个3×2的二维数组)
一步步拆解表达式:
p3→ 指向dat[0](整个第一个二维数组)*p3→ 等价于dat[0],作为二维数组名,在表达式中会自动转换为指向其第一个元素的指针(类型为int(*)[2]),指向dat[0][0](第一个一维数组)*(*p3)→ 等价于dat[0][0],作为一维数组名,再次自动转换为指向其第一个元素的指针(类型为int*),指向dat[0][0][0](值为1的地址)(*(*p3))+4→ 这个int指针向后偏移4个int长度,指向的位置正好是dat[0][2][0](也就是5的地址,从1开始数第5个元素)*(*(*(p3))+4)→ 取该地址对应的值,结果就是5
二、纠正你的猜测
(*p3)[3][2] 属于越界访问,因为 *p3 就是 dat[0],它是一个3行2列的二维数组:
- 行下标范围是
0~2,列下标范围是0~1 - 要取6的话,正确写法是
(*p3)[2][1],等价于dat[0][2][1]
三、学习方向建议
- 先吃透数组的内存连续存储特性:多维数组本质是数组的数组,内存里没有“维度”之分,只是逻辑上的划分,比如三维数组就是连续的一串int值
- 重点掌握数组名的隐式转换规则:数组名在大多数表达式里会变成指向第一个元素的指针,只有在
sizeof(数组名)、&数组名等少数场景下才保留数组类型 - 从低到高练习指针层级:先练一维数组指针(
int*),再练二维数组指针(int(*)[n]),最后过渡到三维,每一步都打印指针地址、取值来验证 - 多写小测试代码:比如打印
p3、*p3、*(*p3)的地址,对比dat、dat[0]、dat[0][0]的地址,直观理解指针指向关系
附上你的测试代码:
#include <stdio.h> void main() { int dat[2][3][2] = { { {1, 2}, {3, 4}, {5, 6} }, { {7, 8}, {9, 19}, {11, 12} } }; int *p1, *p2, (*p3)[3][2]; p3 = dat; printf("%d,", *(*(*(p3))+4)); // 输出5 return 0; }
内容的提问来源于stack exchange,提问作者hong_dynamic
相关产品推荐
相关产品推荐

