C++局部变量与全局变量
困难24变量的小房间和大操场:C++ 局部变量与全局变量
变量就像我们生活中的“小盒子”,用来存东西。在C++里,有些“盒子”只能在一个小房间(函数)里用,有些却能在整个大楼(程序)里用。学会区分它们,能帮你避免很多程序出错的麻烦。
局部变量:只能在自己房间里用的盒子
想象一下,你在教室里有一个属于自己的文具盒。这个文具盒只有你自己能用,别人不能随便拿。在C++里,定义在函数(比如main函数)内部的变量就是局部变量。它只在那个函数的花括号 {} 里有效,一旦出了这个函数,它就消失了。
特点:
- 只在定义它的函数(或花括号块)内有效
- 函数执行结束后自动销毁
- 不同函数可以有同名的局部变量,互不影响
- 局部变量必须在使用前定义
来看个例子:
#include <iostream>
using namespace std;
void myFunction() {
int localVar = 10; // 局部变量,只在myFunction里有效
cout << "局部变量:" << localVar << endl;
}
int main() {
// cout << localVar; // 错误!这里不能用localVar,因为它已经在函数外了
myFunction(); // 调用函数,输出10
return 0;
}
生活中的例子:你房间里的零花钱,只在你自己房间里能用。你到客厅,就不能直接拿房间里的零花钱(除非你回去拿)。同样,函数里的局部变量,其他函数不能直接访问。
注意事项:如果你在花括号内再写一对花括号(嵌套的块),里面的变量也只在这个内层块有效。比如:
int main() {
int outer = 5; // 外层变量
{
int inner = 10; // 内层变量,只在这一对花括号内有效
cout << inner << endl; // 正确
}
// cout << inner; // 错误!inner已经不存在了
cout << outer << endl; // 正确,outer还在
return 0;
}
全局变量:整个学校都能用的盒子
学校里有一些公共物品,比如操场上的篮球,所有同学都可以玩。在C++里,定义在所有函数外面的变量就是全局变量。它从定义的地方开始,一直到程序结束,所有函数都能访问它。
特点:
- 定义在所有函数外部(一般放在
#include之后) - 整个程序(所有函数)都可以读和修改
- 程序启动时创建,程序结束时销毁
- 如果没初始化,会被自动设为0(全局变量默认初始化为0)
比如:
#include <iostream>
using namespace std;
int globalVar = 100; // 全局变量,所有函数都能用
void showGlobal() {
cout << "全局变量:" << globalVar << endl;
}
int main() {
showGlobal(); // 输出100
globalVar = 200; // 在main里也能修改它
cout << "修改后:" << globalVar << endl; // 输出200
return 0;
}
生活中的例子:学校公告栏上的通知,全校师生都能看到,也能贴新的上去。全局变量就像这个公告栏,任何函数都可以查看和修改它。
如果名字碰巧一样怎么办?
如果函数内部又定义了一个和全局变量同名的局部变量,那么在函数内部,程序会优先使用局部变量,全局变量暂时被“藏起来”了。这就像你手上拿着自己的小篮球,就暂时不会去玩学校的大篮球了。
#include <iostream>
using namespace std;
int box = 5; // 全局盒子
int main() {
int box = 3; // 局部盒子,和全局同名
cout << "局部盒子:" << box << endl; // 输出3
// 想访问全局box?需要用 ::box(作用域运算符)
cout << "全局盒子:" << ::box << endl; // 输出5
return 0;
}
这里的::叫做作用域运算符,它的左边什么都不写时,表示“全局作用域”。使用::box就能强制访问被隐藏的全局变量。
小心:这种同名情况很容易让新手搞混。建议除非有特殊理由,否则尽量不要让局部变量和全局变量同名,以免造成阅读困难。
新手常犯的错误
-
在函数外访问局部变量
void func() { int x = 10; // 局部变量 } int main() { cout << x; // 错误!x不存在于main中 }解决办法:把需要共享的数据提到函数外作为全局变量,或者通过函数参数传递。
-
忘记全局变量会被所有函数修改
int score = 100; // 全局变量 void addScore() { score += 50; // 修改了全局变量 } int main() { addScore(); cout << score; // 输出150,原来100被改了 }全局变量太“自由”,如果多个函数都修改它,程序容易变得难以调试。所以尽量少用全局变量,多用局部变量+函数参数。
-
在局部变量定义之前使用它
int main() { cout << a; // 错误!a还没定义 int a = 5; }局部变量必须在开始使用之前声明(定义),不能先使用后定义。
-
混淆不同块的局部变量
int main() { for (int i = 0; i < 5; i++) { int temp = i * 2; } cout << temp; // 错误!temp在循环外不存在 }循环内部定义的局部变量,循环结束后就消失了。
完整示例:零花钱统计程序
下面是一个完整的例子,结合了局部变量和全局变量。程序统计你今天花掉的零花钱和剩下的钱。
#include <iostream>
using namespace std;
int wallet = 50; // 全局变量:钱包里总共有50元
void spendMoney(int cost) {
int today = cost; // 局部变量:今天花的钱
wallet = wallet - today; // 修改全局变量
cout << "今天花了" << today << "元,钱包还剩" << wallet << "元" << endl;
}
int main() {
cout << "初始钱包:" << wallet << "元" << endl;
spendMoney(20); // 今天花了20元
spendMoney(15); // 明天又花了15元
// 尝试打印today?不行,因为today是spendMoney里的局部变量
// cout << today; // 错误!
// 但wallet可以访问,因为它是全局变量
cout << "最终钱包还剩" << wallet << "元" << endl;
return 0;
}
运行结果:
初始钱包:50元
今天花了20元,钱包还剩30元
今天花了15元,钱包还剩15元
最终钱包还剩15元
相关指引
如果你对“变量在哪里能用”这个话题感兴趣,还可以学习:
- 作用域(Scope):除了局部和全局,还有块作用域(花括号内)、函数作用域等。
- 命名空间(namespace):比如
std::,可以把全局变量分组,避免名字冲突。 - 静态变量(static):一种特殊的局部变量,函数结束后不会被销毁,下次调用时还能记住上次的值。
- 全局变量的替代方案:用函数参数和返回值来传递数据,代码更安全、更易读。
从局部变量和全局变量开始,你就能慢慢理解程序里数据的“地盘”了。多写几个小例子试试,很快你就能掌握它们!
例题精讲
下面关于C++中全局变量和局部变量的说法,正确的是?
在C++中,如果一个全局变量没有显式初始化,它的默认值是多少?
在一个函数内部定义的局部变量,当函数返回后,该变量的值仍然保留,直到程序结束。
以下程序的输出结果是:___
int x = 10;
int main() {
int x = 20;
cout << x;
return 0;
}以下程序的输出结果是:___
int a = 1;
void func() {
a++;
}
int main() {
func();
cout << a;
return 0;
}