在定义了数组 int arr[10]; 后,表达式 arr 和表达式 &arr[0] 总是等价的。
看到数组名和取地址表达式并列,第一反应是"数组名在表达式中会衰减成首元素地址",但必须警惕"总是"这个绝对化表述。这类题的通法是:先确认衰减规则(数组名在多数表达式中确实等价于首元素地址),再寻找反例场景(sizeof、取整个数组地址、函数返回等),最后对比类型差异。
选项 B 正确,因为存在多个反例。学生常误以为"地址相同就等价",忽略了 C++ 中类型系统的重要性。sizeof(arr) 返回整个数组字节数,而 sizeof(&arr[0]) 返回指针大小;&arr 的类型是 int(*)[10](指向整个数组的指针),与 int* 不同;函数返回时 arr 会衰减成 int*,但 &arr[0] 保持 int* 类型。这些差异在类型检查、数组操作和函数签名中都会体现。
本题考查 GESP 七级《C++ 程序设计》中"数组与指针关系"模块。命题人专门设置这道题,就是要卡住大量考生对"数组衰减"理解的表面化——他们背下了"数组名等于首地址"这条规则,却忽略了衰减是有条件、有边界的。
看到 arr 和 &arr[0] 并列,先确认:在绝大多数表达式中,数组名确实会衰减成指向首元素的指针,此时两者值相同。但"总是"意味着任何场景都要成立,必须寻找反例。
关键观察是 sizeof 运算符:sizeof(arr) 对数组名不进行衰减,返回整个数组的字节数(10×4=40);而 &arr[0] 是取地址表达式,sizeof(&arr[0]) 返回指针大小(64 位系统为 8)。数值直接不同。
再观察取整个数组地址:&arr 的类型是 int(*)[10],指向整个数组;&arr[0] 的类型是 int*,指向单个元素。类型不同,后续运算行为也不同。