小杨用二维数组记录仓库货物数量。执行下面代码后,变量 x 的值是( )。
int goods[3][4] = {{2, 4, 6, 8}, {10, 12, 14, 16}, {18, 20, 22, 24}};
int (*p)[4] = goods;
int x = *(*(p + 1) + 2);看到二维数组指针声明,先定位 p 指向首行;p+1 下移一行;*(p+1) 解引用得第二行;再 +2 偏移列;最后解引用取值。本质是内存地址的逐层运算。
A 错在把 +2 当成 +1,C 错在把 p+1 当成 p+2,D 错在把行号当成列号。
本题考查 GESP 四级《C++ 程序设计》模块 2「数组与指针」中的二维数组指针声明与指针运算。命题人把这道题放在这里,就是要卡住那些只背过「数组名是首地址」但没真正理解「指针运算如何映射到数组下标」的考生——四级里这类题占比约 15%,错选率常年超过 40%。
goods[3][4] 内存布局:
行 0: [0][0]=2 [0][1]=4 [0][2]=6 [0][3]=8
行 1: [1][0]=10 [1][1]=12 [1][2]=14 [1][3]=16
行 2: [2][0]=18 [2][1]=20 [2][2]=22 [2][3]=24int (*p)[4] = goods; 声明 p 为「指向 4 个 int 的指针」,p 初始指向 goods[0](首行)。p + 1 按「行」移动,指向 goods[1](第二行)。*(p + 1) 解引用得第二行这个数组对象。*(p + 1) + 2 在第二行内偏移 2 列,指向 goods[1][2]。*(*(p + 1) + 2) 最终取值,即 goods[1][2] = 14。通法:int (*p)[M] = arr; 时,p + i 指向第 i 行,*(p + i) + j 指向第 i 行第 j 列,*(*(p + i) + j) 取值。