C语言:如何理解对数组指针解引用得到元素指针?
理解数组指针解引用后的类型变化
嘿,这个问题我当初刚啃C语言指针的时候也绕了好半天,咱们把它拆成两步就好懂了——先搞清楚指针指向的是什么对象,再回忆一下数组名的隐式转换规则,答案就出来了!
先看 int (*p1)[3] 解引用的情况
p1 是一个指向「包含3个int元素的数组」的指针,也就是说它指向的对象类型是 int[3]。当你对 p1 解引用(*p1)时,你得到的就是这个 int[3] 类型的数组本身。
但别忘了C语言的核心规则:除了少数例外情况(比如用在sizeof、&运算符后),数组名会自动隐式转换为指向数组第一个元素的指针。这里的*p1就是一个int[3]数组,所以它会被转换成指向第一个int元素的指针——也就是int*类型。
举个实际的例子验证:
int a[3] = {1,2,3}; int (*p1)[3] = &a; int* ptr = *p1; // 完全合法,ptr现在指向a[0] printf("%d", *ptr); // 输出1,和a[0]的值一致
再看 int (*p3)[2][3] 解引用的情况
p3 是一个指向「2行3列的二维数组」的指针,它指向的对象类型是 int[2][3]。解引用*p3后,你得到的就是这个二维数组本身。
同样套用数组的隐式转换规则:二维数组int[2][3]的第一个元素是什么?是它的第一行,也就是一个int[3]类型的一维数组。所以这个二维数组名会被转换成指向其第一个元素(int[3]数组)的指针——也就是int (*)[3]类型(指向3个int的数组的指针)。
再举个例子:
int b[2][3] = {{1,2,3}, {4,5,6}}; int (*p3)[2][3] = &b; int (*row_ptr)[3] = *p3; // 合法,row_ptr现在指向b的第一行 printf("%d", (*row_ptr)[0]); // 输出1,和b[0][0]的值一致
核心总结
解引用数组指针的本质是获取它指向的数组对象,之后这个数组对象会触发「数组到指针的隐式转换」:
- 一维数组
int[N]转换为int*(指向第一个int元素) - 二维数组
int[M][N]转换为int (*)[N](指向第一个int[N]行数组) - 以此类推,更高维的数组转换后,指针的类型会保留最后一维的大小
内容的提问来源于stack exchange,提问作者Rick
相关产品推荐
相关产品推荐

