考纲要求
- 理解形参是函数定义中的变量,实参是调用时传入的具体值,二者通过参数传递建立联系。
- 掌握局部变量的作用域:只在定义它的函数或代码块内可见,离开即失效。
- 理解全局变量在整个程序内可见,生命周期贯穿程序运行。
- 知道同名变量在不同作用域中可以共存,内层会遮蔽外层。
典型题型
- 给出含多个作用域的程序,要求写出输出结果。
- 判断某个变量在指定位置是否可见。
- 比较局部变量与全局变量的初值。
常见错误
- 以为形参改名会影响调用结果,形参名只在函数内部有意义。
- 在代码块内定义同名变量,误以为修改的是外层变量。
- 依赖局部变量的默认初值写程序,而未初始化的局部变量值不确定。
- 把循环体内定义的变量拿到循环外使用,导致编译报错。
深入理解
形参是实参的副本
调用 add(x, y) 时,x 和 y 是实参,函数定义里的 a 和 b 是形参。默认的值传递会把实参的值复制一份给形参,函数里改 a 不会影响外面的 x——它们是两块不同的内存。
理解这一点的最快方式是记住:形参在函数开始时被创建,在函数结束时被销毁。每次调用都会重新创建一份,两次调用之间互不影响。这解释了为什么递归函数里每一层的局部变量都是独立的。
作用域决定「这个名字属于谁」
局部变量只在定义它的 { } 块内有效。块结束时变量消失,外面再用就是未定义。在 for 的初始化里定义的变量只在循环内有效:for (int i = 0; ...) 结束后再用 i 会报错。
全局变量定义在所有函数之外,整个文件都能访问,未初始化时自动为 0(局部变量不会)。当局部变量与全局变量同名时,局部变量会遮蔽全局变量,块内访问的是局部那个,块结束才恢复。给一段含同名变量的程序问「这一行输出什么」,就是按「从里往外找」的顺序判断。
生命周期与作用域不是一回事
作用域回答「在哪能看见这个名字」,生命周期回答「这块内存什么时候存在」。局部变量两者通常一致,但全局变量和静态变量的生命周期贯穿整个程序,作用域却可能只在某个文件里。
题目里常用「函数返回后,它的局部变量还在吗」来考这一点。答案是不在——函数返回时局部变量已被销毁,返回它的地址会得到一个悬空指针,程序可能读到垃圾值。这是四级里指针与函数交叉的常见陷阱。
自编例题
内外层同名变量
下面程序输出什么?
int x = 10;
int main() {
cout << x << endl; // 10
int x = 5;
cout << x << endl; // 5
{ int x = 3; cout << x << endl; } // 3
cout << x << endl; // 5
}第一行访问的是全局变量 x,输出 10。进入 main 后定义局部变量 x 并初始化为 5,遮蔽了全局变量,输出 5。内层代码块中又定义了一个 x,输出 3,离开代码块后它失效。最后一行回到 main 的局部 x,仍然输出 5。作用域按就近原则匹配,理解这一点才能读懂变量到底指向哪一个。全局变量虽然方便,但过多使用会让程序难以调试。
相关真题
这块内容在整条路线里的位置:GESP C++ 4 级备考路径。
READY TO START
开始练习
先做一套本级别测评,报告会指出哪些知识点需要重点补;再回到本页对照考纲要求逐条核对,把不确定的条目记下来集中练。
常见问题
形参改变会影响实参吗?
普通值传递不会,形参只是实参的副本。只有引用传递或指针传递才能在函数内修改调用处的变量。
全局变量有什么风险?
任何函数都能修改它,容易出现意料之外的相互影响;大型程序应尽量用局部变量和参数传递数据。
局部变量不初始化值是多少?
不确定,可能是任意值。使用前必须赋值,不能假设默认为 0。全局变量和静态变量才会自动初始化为 0。
