静态局部变量(static local variable)是在函数内部声明的,具有静态存储期限的变量。这意味着它的生命周期从程序开始时开始,直到程序结束,而不是在函数调用时创建和销毁。静态局部变量只会被初始化一次,即使在函数被多次调用时也是如此。它们的值在函数调用之间保持不变。
静态局部变量的例子:
#include <iostream>
void incrementAndPrint() {
static int count = 0; // 静态局部变量
count++; // 每次调用时增加count的值
std::cout << count << std::endl;
}
int main() {
incrementAndPrint(); // 输出:1
incrementAndPrint(); // 输出:2
incrementAndPrint(); // 输出:3
return 0;
}
在这个例子中,count
是一个静态局部变量。每次调用incrementAndPrint
函数时,count
的值都会增加,并且记住上一次调用的值,因为它在函数调用之间保持不变。第一次调用时,count
初始化为0,然后增加到1,并打印出来。后续的调用会继续增加count
的值并打印。如果count
不是静态的,那么每次调用incrementAndPrint
时,count
都会被重新初始化为0,因此每次都会打印1。
在C++中,静态变量主要有两种类型,它们的存储期限都是静态的,但是它们的作用域不同:
- 静态局部变量(Static Local Variables):
- 静态局部变量是在函数内部声明的,但它们的生命周期是整个程序运行期间,而不是函数调用的生命周期。
- 它们仅在函数内部可见,不能被其他函数访问。
- 静态局部变量只在第一次调用函数时初始化,之后每次调用时保持上一次的值。
- 静态全局变量(Static Global Variables):
- 静态全局变量是在文件作用域内声明的,它们的生命周期也是整个程序运行期间。
- 它们在声明它们的文件内可见,但在其他文件中默认是不可见的,即它们具有内部链接性(internal linkage)。
- 如果没有在声明时初始化,静态全局变量会被自动初始化为0。
- 通过使用
extern
关键字,可以在其他文件中声明静态全局变量,从而使得它们可以被其他文件访问。
除了这两种类型,C++中的类成员也可以是静态的,这意味着无论创建了多少个类的对象,静态成员都只有一个副本:
- 静态类成员(Static Class Members):
- 静态类成员是属于类的,而不是属于类的任何一个对象的。
- 它们在类的所有对象之间共享,不需要通过对象来访问。
- 静态类成员可以在类定义内部或外部进行初始化,但通常是在类定义外部进行。
这些是C++中主要的静态变量类型,它们在程序中的作用和用途各不相同。
在C++中,不同的作用域通常与特定的生命周期相关联。以下是各种作用域与对应的变量生命周期:
- 全局作用域(Global Scope):
- 对应的变量生命周期:静态存储期限(Static Storage Duration)。
- 全局变量在程序开始时创建,在程序结束时销毁。
- 局部作用域(Local Scope):
- 自动局部变量(Auto Local Variables):自动存储期限(Auto Storage Duration)。
- 在进入块(如函数内部)时创建,在退出块时销毁。
- 静态局部变量(Static Local Variables):静态存储期限(Static Storage Duration)。
- 在程序开始时创建,但在第一次使用时初始化,只在定义它们的函数内部可见,在程序结束时销毁。
- 自动局部变量(Auto Local Variables):自动存储期限(Auto Storage Duration)。
- 类作用域(Class Scope):
- 对应的变量生命周期:依赖于成员的存储类别。
- 类成员变量可以是静态或非静态的,静态类成员具有静态存储期限,非静态成员变量的生命周期与类对象的生命周期相同。
- 命名空间作用域(Namespace Scope):
- 对应的变量生命周期:静态存储期限(Static Storage Duration)。
- 在命名空间中定义的变量在程序开始时创建,在程序结束时销毁。
- 函数原型作用域(Function Prototype Scope):
- 对应的变量生命周期:没有实际的生命周期,因为函数原型作用域只用于参数声明,不创建实际的存储空间。
- 块作用域(Block Scope):
- 对应的变量生命周期:自动存储期限(Auto Storage Duration)。
- 在进入块(如循环或条件语句内部)时创建,在退出块时销毁。
- 线程存储期限(Thread Storage Duration):
- 对应的变量生命周期:线程存储期限(Thread Storage Duration)。
- 使用
thread_local
关键字声明的变量在每个线程开始时创建,在线程结束时销毁。
- 动态存储期限(Dynamic Storage Duration):
- 对应的变量生命周期:动态存储期限(Dynamic Storage Duration)。
- 使用
new
关键字在堆上分配的变量在调用delete
时销毁。
需要注意的是,虽然作用域通常与特定的生命周期相关联,但有时也可以通过使用存储类说明符(如static
、extern
、thread_local
)来改变这种默认关联。例如,一个在局部作用域内声明的变量可以通过使用static
关键字将其生命周期变为静态存储期限。