C语言二维数组算术解引用*(arr+1)[1]结果异常原因咨询
核心原因:运算符优先级导致表达式解析顺序和预期不符
你计算错误的核心原因是搞错了解引用运算符*和下标运算符[]的优先级:C语言中后缀下标运算符[]的优先级高于一元解引用运算符*,因此*(arr+1)[1]不会按照你预想的(*(arr+1))[1]顺序计算,实际解析顺序是*((arr+1)[1])。
逐步骤拆解实际运算逻辑
- 第一步:先计算
(arr+1)[1]。C语言标准明确规定,下标运算a[b]完全等价于*(a + b),因此(arr+1)[1] = *((arr+1) + 1) = *(arr + 2)。
这里要注意arr的类型是长度为2的short数组指针(short (*)[2]),因此指针算术的偏移单位始终是「1个长度为2的short一维数组」,不管是第一次arr+1还是第二次(arr+1)+1,每次加1的偏移量都是2*sizeof(short),最终*(arr+2)得到的是二维数组的第三个一维子数组arr[2],数组会隐式退化为指向arr[2][0]的short*类型指针。 - 第二步:计算最外层的解引用
*((arr+1)[1])。此时操作数是指向arr[2][0]的short指针,解引用后拿到的就是arr[2][0]的值17,和你实际运行的结果一致。
预期写法的正确形式
如果你想拿到arr[1][1]的值14,必须给arr+1加上括号强制优先计算,对应表达式为(*(arr+1))[1],括号提升了运算优先级,会先解引用拿到arr[1]子数组的起始地址,再做下标偏移访问第二个元素。
你可以运行以下验证代码确认结果:
#include <stdio.h> int main(void) { short arr[3][2]={3,5,11,14,17,20}; printf("%d %d\n",*(arr+1)[1],**(arr+2)); // 输出17 17 printf("%d\n",(*(arr+1))[1]); // 输出14,即你预期的arr[1][1]值 return 0; }
补充说明第二个表达式
**(arr+2)的逻辑:arr+2指向arr[2]子数组,第一次解引用拿到arr[2]子数组并退化为指向arr[2][0]的指针,第二次解引用拿到arr[2][0]的值,因此输出17,和第一个表达式结果一致。
内容的提问来源于stack exchange,提问作者dem
相关产品推荐
相关产品推荐

