CC++ & Algorithm

C++局部变量与全局变量

困难24
语言版本:C++Python
概述:就像教室里的个人物品和学校公物,局部变量只能在函数内使用,全局变量整个程序都能访问。

变量的小房间和大操场: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就能强制访问被隐藏的全局变量。

小心:这种同名情况很容易让新手搞混。建议除非有特殊理由,否则尽量不要让局部变量和全局变量同名,以免造成阅读困难。

新手常犯的错误

  1. 在函数外访问局部变量

    void func() {
        int x = 10; // 局部变量
    }
    int main() {
        cout << x; // 错误!x不存在于main中
    }
    

    解决办法:把需要共享的数据提到函数外作为全局变量,或者通过函数参数传递。

  2. 忘记全局变量会被所有函数修改

    int score = 100; // 全局变量
    void addScore() {
        score += 50; // 修改了全局变量
    }
    int main() {
        addScore();
        cout << score; // 输出150,原来100被改了
    }
    

    全局变量太“自由”,如果多个函数都修改它,程序容易变得难以调试。所以尽量少用全局变量,多用局部变量+函数参数。

  3. 在局部变量定义之前使用它

    int main() {
        cout << a; // 错误!a还没定义
        int a = 5;
    }
    

    局部变量必须在开始使用之前声明(定义),不能先使用后定义。

  4. 混淆不同块的局部变量

    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):一种特殊的局部变量,函数结束后不会被销毁,下次调用时还能记住上次的值。
  • 全局变量的替代方案:用函数参数和返回值来传递数据,代码更安全、更易读。

从局部变量和全局变量开始,你就能慢慢理解程序里数据的“地盘”了。多写几个小例子试试,很快你就能掌握它们!

例题精讲

1单选题

下面关于C++中全局变量和局部变量的说法,正确的是?

A全局变量和局部变量可以同名,在局部作用域内全局变量被隐藏
B全局变量必须在所有函数之前定义
C局部变量的作用域从定义处开始到文件结束
D全局变量存储在栈区
2单选题

在C++中,如果一个全局变量没有显式初始化,它的默认值是多少?

A0
B随机值
Cundefined
DNULL
3判断题

在一个函数内部定义的局部变量,当函数返回后,该变量的值仍然保留,直到程序结束。

4填空题
以下程序的输出结果是:___
int x = 10;
int main() {
    int x = 20;
    cout << x;
    return 0;
}
5填空题
以下程序的输出结果是:___
int a = 1;
void func() {
    a++;
}
int main() {
    func();
    cout << a;
    return 0;
}