C++ 存储类
在本文中,您将了解 C++ 中的不同存储类。即:局部、全局、静态局部、寄存器和线程局部。
C++ 中的每个变量都有两个特性:数据类型和存储类。
数据类型指定可以存储在变量中的数据类型。例如: int
, float
, char
等。
存储类控制变量的两个不同属性:生存期(确定变量可以存在多长时间)和范围(确定程序的哪个部分可以访问它)。
根据变量的存储类别,它可以分为 4 种主要类型:
- 局部变量
- 在函数内部定义的变量。局部变量的作用域和声明周仅限于定义它的函数。
- 全局变量
- 在所有函数之外定义的变量。全局变量的作用域是整个程序。
- 静态局部变量
- 使用
static
关键字在函数内部定义的变量。它的作用域是定义它的函数,但是它的生命周期是整个程序。 - 寄存器变量
- 关键字
register
用于指定寄存器变量。C++ 11 已弃用。 - 线程本地存储
- 关键字
thread_local
定义的变量。在每个线程中都有一个副本。
局部变量
在函数内部定义的变量(在函数体内部大括号之间定义)称为局部变量或自动变量。
它的作用域仅限于定义它的函数。简单来说,局部变量存在并且只能在函数内部访问。
当函数退出时,局部变量的生命周期结束(它被销毁)。
示例 1:局部变量
#include <iostream>
using namespace std;
void test();
int main()
{
// main() 中的局部变量
int var = 5;
test();
// 错误的: var1 不在 main() 中定义的
var1 = 9;
}
void test()
{
// test 中的局部变量
int var1;
var1 = 6;
// 错误的: test() 内部不能使用 var
cout << var;
}
变量 var
不能用于 test()
内部; var1
不能在 main()
函数内部使用。
关键字 auto
之前也用于定义局部变量: auto int var;
但是,在 C++11 之后 auto
有不同的含义,不应用于定义局部变量。
全局变量
如果在所有函数之外定义了一个变量,则它被称为全局变量。
全局变量的作用域是整个程序。这意味着,它可以在声明后在程序的任何部分使用和更改。
同样,它的生命也只有在程序结束时才结束。
示例 2:全局变量
#include <iostream>
using namespace std;
// 声明全局变量
int c = 12;
void test();
int main()
{
++c;
// Outputs 13
cout << c <<endl;
test();
return 0;
}
void test()
{
++c;
// Outputs 14
cout << c;
}
输出
13
14
在上面的程序中, c
是一个全局变量。这个变量对函数 main()
和 test()
都是可见的。
静态局部变量
关键字 static
用于指定静态变量。例如:
... .. ...
int main()
{
static float a;
... .. ...
}
静态局部变量仅存在于声明它的函数内(类似于局部变量),但其生命周期从函数被调用时开始,并仅在程序结束时结束。
局部变量和静态变量的主要区别在于,静态变量的值在程序结束时保持不变。
示例 3:静态局部变量
#include <iostream>
using namespace std;
void test()
{
// var is a static variable
static int var = 0;
++var;
cout << var << endl;
}
int main()
{
test();
test();
return 0;
}
输出
1
2
在上面的程序中, test()
函数被调用了 2 次。
在第一次调用期间,变量 var
声明为静态变量并初始化为 0
。然后将 1
加到 var
,并将它显示在屏幕上。此时输出 1
。
当函数 test()
返回时,变量 var
仍然存在,因为它是一个静态变量。
在第二次函数调用期间, var
变量不会被重复建造。然后将 1
加到 var
,并将它显示在屏幕上。此时输出 2
。
如果 var
未指定为静态变量,则上述程序的输出
1
1
寄存器变量(在 C++11 中已弃用)
关键字 register
用于指定寄存器变量。
寄存器变量类似于自动变量,仅存在于特定函数中。它应该比局部变量更快。
如果程序遇到寄存器变量,它会将变量存储在处理器的寄存器中(如果可用),而不是内存中。这使它比局部变量更快。
但是,此关键字在 C++ 11 中已弃用,不应使用。
线程本地存储
线程局部存储是一种分配变量的机制,这样每个现存线程就有一个变量实例。
关键字 thread_local
用于此目的。