五、全局变量、局部变量、static 静态变量
概念: 变量根据其声明的位置和 static 关键字的使用,拥有不同的作用域和生命周期。
- 全局变量 (Global Variable): 在所有函数外部定义的变量。它们在程序开始执行时被创建,在程序结束时被销毁,具有全局作用域,可以被程序中的任何函数访问。
- 局部变量 (Local Variable): 在函数内部或复合语句(例如
if语句、循环语句)内部定义的变量。它们在定义时被创建,在所在的代码块执行完毕后被销毁,具有局部作用域,只能在其定义的代码块内部被访问。 static静态变量 (Static Variable):- 局部静态变量: 在函数内部用
static关键字声明的变量。它只在第一次执行到其定义语句时被初始化一次,之后的函数调用不会再次初始化。 它的生命周期贯穿整个程序执行期间,但作用域仍然是局部的,只能在定义它的函数内部访问。 - 全局静态变量: 在所有函数外部用
static关键字声明的变量。它的作用域被限制在声明它的源文件中,其他源文件无法访问。这可以避免命名冲突。
- 局部静态变量: 在函数内部用
示例代码:
#include <iostream>
// 全局变量
static int globalVar = 10;
void func() {
// 局部变量
int localVar = 20;
// static 静态局部变量
static int staticVar = 30;
static int* ptr = new int(100);
std::cout << "函数 func 被调用" << std::endl;
std::cout << "全局变量: " << globalVar << ",地址: " << &globalVar << std::endl;
std::cout << "局部变量: " << localVar << ",地址: " << &localVar << std::endl;
std::cout << "静态变量: " << staticVar << ",地址: " << &staticVar << std::endl;
localVar++;
staticVar++;
}
int main() {
std::cout << "main 函数中的全局变量: " << globalVar << std::endl;
func();
func();
return 0;
}
讲解要点:
- 三种变量的作用域和生命周期:
| 变量类型 | 作用域 | 生命周期 | 初始化时机 |
|---|---|---|---|
| 全局变量 | 整个程序 | 程序开始到程序结束 | 程序启动时 |
| 局部变量 | 定义它的代码块 | 定义时创建,代码块结束时销毁 | 每次进入代码块时 |
| 静态局部变量 | 定义它的函数 | 程序开始到程序结束 | 第一次执行到定义语句时 |
| 静态全局变量 | 声明它的源文件 | 程序开始到程序结束 | 程序启动时 |
static关键字的作用:- 修饰局部变量: 延长局部变量的生命周期,使其在函数多次调用之间保持状态。
- 修饰全局变量: 限制全局变量的作用域,使其只能在当前源文件中访问。
- 修饰类的成员变量: 使类的所有对象共享同一个变量,属于类而不是类的某个特定对象。
- 修饰类的成员函数: 使成员函数不依赖于类的具体对象而存在,可以通过类名直接调用。
- 全局变量的使用注意事项: 虽然全局变量方便访问,但过度使用全局变量会降低代码的模块化程度,增加命名冲突的风险,并可能导致程序难以维护和调试。 应该谨慎使用全局变量,尽可能使用局部变量或将数据封装在类中。
练习与思考:
- 编写一个程序,演示静态局部变量在函数多次调用之间保持状态的特性。
- 思考为什么全局静态变量可以避免命名冲突?
- 查阅资料,了解 C++ 中
extern关键字的作用,以及它与全局变量的关系。