文章目录
- 0. 语法
- 1. 自动存储类
- 自动存储类对象的属性
- 自动存储类的例子
- 2. 外部存储类
- extern存储类对象的属性
- extern存储类的例子
- 3. 静态存储类
- 静态存储类的属性
- 静态存储类的例子
- 4. 寄存器存储类
- 寄存器存储类对象的属性
- 寄存器存储类例子
- 5. 可变(mutable)存储类
- 可变存储类的属性
- 可变存储类的例子
- 6. thread_local存储类
- thread_local存储类属性
- thread_local存储类的例子
C++存储类用于描述变量/函数的特性。它确定了生命周期、可见性、默认值和存储位置,这有助于我们在程序运行时跟踪特定变量。存储类说明符用于指定变量的存储类。
0. 语法
要指定变量的存储类,请遵循以下语法:
storage_class var_data_type var_name;
C++使用了6个存储类,如下所示:
- auto Storage Class
- register Storage Class
- extern Storage Class
- static Storage Class
- mutable Storage Class
- thread_local Storage Class
以下是对每个存储类的详细说明:
1. 自动存储类
自动存储类是块内声明的所有变量的默认类。auto 代表自动,块中声明的所有局部变量都自动属于此类。
自动存储类对象的属性
- 范围:本地/局部
- 默认值:垃圾值
- 内存位置:RAM
- 生命期:直到其范围结束
自动存储类的例子
// C++ Program to illustrate the auto storage class
// variables
#include <iostream>
using namespace std;void autoStorageClass()
{cout << "Demonstrating auto class\n";// Declaring an auto variableint a = 32;float b = 3.2;char* c = "GeeksforGeeks";char d = 'G';// printing the auto variablescout << a << " \n";cout << b << " \n";cout << c << " \n";cout << d << " \n";
}int main()
{// To demonstrate auto Storage ClassautoStorageClass();return 0;
}
输出
Demonstrating auto class
32
3.2
GeeksforGeeks
G
注意:在C++早期,我们可以使用auto关键字显式声明自动变量,但在C++11之后,auto关键字的含义发生了变化,我们不能再使用它来定义自动变量。
2. 外部存储类
extern存储类只是简单地告诉我们变量是在其他地方定义的,而不是在使用它的同一块中(即外部链接)。基本上,该值在不同的块中被赋值,也可以在不同的块中重写/更改。外部变量只不过是一个全局变量,该全局变量在声明时使用合法值初始化,以便在其他地方使用。
在任何函数/块中的声明/定义之前放置 “extern” 关键字,可以将普通全局变量设置为 extern。使用外部变量的主要目的是,可以在大型程序的两个不同文件之间访问它们。
extern存储类对象的属性
- 范围:全局
- 默认值:0
-
- 内存位置:RAM
- 生命期:直到程序结束
extern存储类的例子
// C++ Program to illustrate the extern storage class
#include <iostream>
using namespace std;// declaring the variable which is to
// be made extern an initial value can
// also be initialized to x
int x;
void externStorageClass()
{cout << "Demonstrating extern class\n";// telling the compiler that the variable// x is an extern variable and has been// defined elsewhere (above the main// function)extern int x;// printing the extern variables 'x'cout << "Value of the variable 'x'"<< "declared, as extern: " << x << "\n";// value of extern variable x modifiedx = 2;// printing the modified values of// extern variables 'x'cout << "Modified value of the variable 'x'"<< " declared as extern: \n"<< x;
}int main()
{// To demonstrate extern Storage ClassexternStorageClass();return 0;
}
输出
Demonstrating extern class
Value of the variable 'x'declared, as extern: 0
Modified value of the variable 'x' declared as extern:
2
有关外部变量如何工作的更多信息,请查看此链接。
3. 静态存储类
静态存储类用于声明在C++语言中编写程序时常用的静态变量。静态变量具有即使在超出其作用域后也能保留其值的特性!因此,静态变量保存了它们在作用域中最后一次使用的值。
我们可以说,它们只初始化一次,并且一直存在到程序终止。因此,没有分配新的内存,因为它们没有被重新声明。全局静态变量可以在程序中的任何位置访问。
静态存储类的属性
- 范围:本地/局部
- 默认值:0
-
- 内存位置:RAM
- 生命期:直到程序结束
注意:全局静态变量可以在任何函数中访问。
静态存储类的例子
// C++ program to illustrate the static storage class
// objects
#include <iostream>
using namespace std;// Function containing static variables
// memory is retained during execution
int staticFun()
{cout << "For static variables: ";static int count = 0;count++;return count;
}// Function containing non-static variables
// memory is destroyed
int nonStaticFun()
{cout << "For Non-Static variables: ";int count = 0;count++;return count;
}int main()
{// Calling the static partscout << staticFun() << "\n";cout << staticFun() << "\n";// Calling the non-static partscout << nonStaticFun() << "\n";cout << nonStaticFun() << "\n";return 0;
}
输出
For static variables: 1
For static variables: 2
For Non-Static variables: 1
For Non-Static variables: 1
4. 寄存器存储类
寄存器存储类使用“register”关键字声明寄存器变量,该关键字具有与自动变量相同的功能。唯一的区别是,如果有可用的寄存器,编译器会尝试将这些变量存储在微处理器的寄存器中。这使得程序运行时,寄存器变量的使用比存储在内存中的变量的使用快得多。如果没有可用寄存器,则这些寄存器变量仅存储在内存中。
这里需要注意的一个重要而有趣的点是,我们不能使用指针来获得寄存器变量的地址。
寄存器存储类对象的属性
- 范围:本地/局部
- 默认值:垃圾值
-
- 内存位置:CPU中的寄存器或RAM
- 生命期:直到其范围结束
寄存器存储类例子
// C++ Program to illustrate the use of register variables
#include <iostream>
using namespace std;void registerStorageClass()
{cout << "Demonstrating register class\n";// declaring a register variableregister char b = 'G';// printing the register variable 'b'cout << "Value of the variable 'b'"<< " declared as register: " << b;
}
int main()
{// To demonstrate register Storage ClassregisterStorageClass();return 0;
}
输出
Demonstrating register class
Value of the variable 'b' declared as register: G
注意:register关键字在C++17以后的版本中已被弃用。
5. 可变(mutable)存储类
有时需要通过const函数修改类/结构体的一个或多个数据成员,即使您不希望该函数更新类/结构体中的其他成员。使用mutable关键字可以很容易地执行此任务。关键字mutable主要用于允许修改const对象的特定数据成员。
当我们将函数声明为const时,传递给函数的指针就变成了const。给变量添加mutable可以让const指针改变成员。
可变存储类的属性
可变说明符不影响对象的链接或生存期。它将与在该位置声明的正常对象相同。
可变存储类的例子
// C++ program to illustrate the use of mutalbe storage
// class specifiers
#include <iostream>
using std::cout;class Test {
public:int x;// defining mutable variable y// now this can be modifiedmutable int y;Test(){x = 4;y = 10;}
};int main()
{// t1 is set to constantconst Test t1;// trying to change the valuet1.y = 20;cout << t1.y;// Uncommenting below lines// will throw error// t1.x = 8;// cout << t1.x;return 0;
}
输出
20
6. thread_local存储类
thread_local存储类是在C++11中添加的新存储类。我们可以使用thread_local存储类说明符将对象定义为thread_local。thread_local变量可以与其他存储说明符(如static或extern)组合,thread_local对象的属性也会相应更改。
thread_local存储类属性
- 内存位置:RAM
- 生命期:直到它的线程结束
thread_local存储类的例子
// C++ program to illustrate the use of thread_local storage
// sprecifier
#include <iostream>
#include <thread>
using namespace std;// defining thread local variable
thread_local int var = 10;// driver code
int main()
{// thread 1thread th1([]() {cout << "Thread 1 var Value: " << (var += 18) << '\n';});// thread 2thread th2([]() {cout << "Thread 2 var Value: " << (var += 7) << '\n';});// thread 3thread th3([]() {cout << "Thread 3 var Value: " << (var += 13) << '\n';});th1.join();th2.join();th3.join();return 0;
}
输出
Thread 1 var Value: 28
Thread 2 var Value: 17
Thread 3 var Value: 23
可以看到,每个线程都有自己的thread_local变量副本,并且只被分配了在其可调用文件中指定的值。