下面这段代码会输出( )。
int x = 5;
void foo() {
int x = 10;
cout << x << " ";
}
void bar() {
cout << x << " ";
}
int main() {
foo();
bar();
}答案D。指针和数组的代码追踪:画出变量和指针的内存示意图,追踪每次赋值后值的变化。
指针和数组追踪时画内存布局图可以大大简化理解。
【考点】变量作用域|同名遮蔽|局部变量
1. 考纲定位 本题考查 GESP 202509 C++ 四级第 4 模块「函数与作用域」的核心概念:变量作用域与同名遮蔽。绝大多数考生会混淆全局变量与局部变量的生存周期,误以为 bar() 中的 x 仍指向 main() 中最初的 5,却忽略 foo() 内声明的新 x 会遮蔽外部同名变量。
2. 解题思维 推理链条必须分层追踪作用域:main() 中的 x=5 是全局作用域变量;foo() 内部声明 int x=10 创建了新的局部变量,它遮蔽了外层的 x,因此 foo() 中 cout<<x 输出 10;bar() 内部没有新声明 x,它复用 main() 中的 x=5,故 bar() 输出 5。顺序执行 foo() 后 bar(),最终输出为 10 5。
3. 陷阱拆解 命题人精心设计了三个典型误区:A 选项 5 5 源于混淆全局变量与局部变量,误以为 x 始终为 5;B 选项 10 10 误判 foo() 修改了全局 x 且 bar() 仍能看到;C 选项 5 10 则反向错误地认为 foo() 修改了全局 x 但 bar() 未受影响。最阴险的细节在于 foo() 内 int x=10 的声明——它并未修改 main() 中的 x,而是创建了新局部变量。若只背结论而不理解作用域规则,必然掉入此陷阱。
4. 反命题思维 若命题人想考参数传递与引用,可将 foo() 改为 void foo(int x) 并调用 foo(x),此时 bar() 中的 x 仍为 5,但 foo() 输出 10,考察参数遮蔽;若改为 void foo(int &x) 并调用 foo(x),则 bar() 输出会变为 10,考察引用传递。刷到此类题时,先问自己:「命题人想考我什么?是作用域、参数传递还是引用?」