关于以下程序段,说法正确的是( )。
int x=10;
cout<<(x++) + (++x)<<endl;答案A。数组和位运算的代码追踪要特别小心:数组下标从0开始,位运算结果可能不直观。建议画图辅助。
位运算追踪时建议把数字写成二进制形式再逐位计算。
【考点】表达式求值顺序|副作用|未定义行为
1. 考纲定位:GESP 三级"程序执行逻辑"模块。命题人专门卡住"以为 C++ 有严格求值顺序"的考生——自增/自减算子的副作用与求值顺序是 C++ 里最经典的未定义行为陷阱。
2. 解题思维:先识别 x++ 和 ++x 都修改 x,且中间没有序列点(逗号、逻辑/位运算符、分号)。C++11 标准明确规定:同一对象在表达式中被修改超过一次且无序列点分隔,行为未定义。因此不能像 C 或某些教材那样默认"从左到右"计算。
3. 陷阱拆解:B、C、D 都是基于错误直觉——要么假设 x++ 先算(得 10)再 ++x(得 12)凑 22,要么反过来得 21,甚至误算 20。命题人利用"结合性"和"求值顺序"的混淆,让只背结论的考生掉进"以为有确定顺序"的坑。未定义行为的本质是编译器自由,结果可能任何值,甚至崩溃。
4. 反命题思维:如果把表达式改成 (x++, ++x) 或中间加逗号,序列点出现,行为就确定了。刷到类似题先自问"这里有没有序列点?是否修改同一对象超过一次?"——这才是定位未定义行为的黄金法则。