C++PrimerPlus 学习笔记 | 第九章 内存模型和命名空间|2.6 说明符和限定符

本文详细介绍了C++中的存储说明符,如auto、register、static、extern和thread_local,以及cv限定符const和volatile。存储说明符在不同C++标准下有不同的作用,thread_local和mutable是C++11引入的新特性。cv限定符中,const用于禁止变量修改,volatile则用于告知编译器变量值可能在程序未明确修改时改变。此外,还讨论了const在全局变量链接性的影响以及如何通过extern覆盖const的内部链接性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

说明符和限定符

有些被称为存储说明符,或者是cv限定符

存储说明符如下

auto; // 在C++11(不包含C++11)之前表示自动变量,C++11中用于自动类型推导,即C++11(不包含C++11)是存储说明符号,C++11(含C++11)以后不再是存储说明符
register; // 在C++11(不包含C++11)表示寄存器变量,在C++11(包含C++11)之后仅表示自动自动变量
static; 
extern;
thread_local; //(C++11新增)
mutable;

除了thread_local可以跟extern和static结合外,在同一个声明中不可以出现多个修饰符号。

除了thread_local和mutable没有认识外,其他均在前面有说明

cv-限定符号

const; 
volatile; 

其中const表示当变量内存被初始化后,程序不能再对其进行修改。

volatile表示即使程序代码没有对其进行修改,其值仍然可能发生变化。,该关键词的作用主要是更改编译器的优化能力,一般来说在一个程序中同时使用一个值两次,程序可能不是将其读取两次,而是第一次读取时顺手存到寄存器,第二次直接从寄存器取出,这种假设没有外部程序会影响该值,但是如果使用volatile修饰变量,编译器将每次重新读取该值

mutable成员表示即使某个类或者成员为const,其中被mutbale修饰的成员也可以修改,实例如下

struct data{
    char name[100];
    mutable int accesses;
};
const data d = {
    "Llonvne",
    0
};
strcpy(d.name, "Lcosvle"); // 不被允许 d 为常量其成员不允许修改
d.accesses++; // 允许 虽然d 为常量,但是accesses被mutable修饰所以可以修改。

在C++中(此处不包括C语言),const对默认存储类型稍有影响,在默认情况下全局变量的链接性为外部的,但是被const修饰的全局变量的链接性为内部,也就是说在C++看来,全局const定义类似于使用了static修饰符号一样,下述两句语句完全等价

const int a = 1;
const static int a = 1;

C++修改了常量类型的规则,使得程序员更加轻松,假设将一组全局常量放在头文件,并在同一个程序的多个文件中使用这样的头文件,那么处理器将头文件包含到所有的源文件后,所有的源文件都将包含一份全局常量定义,如果全局的链接性是外部的,根据前面的单定义规则,这将出错,也就是说只有一组文件可以包含定义,而另外的文件必须使用extern来引用变量。另外只有未包含extern关键字的才能进行初始化。这将导致许多不必要的麻烦。

因此,**需要为某个文件使用一组定义,而其他文件使用另外一组声明,然而由于外部定义的const数据的链接性仍然是内部,因此可以在所有文件使用相同的声明。**所以C++鼓励将const声明写入头文件,由于const内部链接性,他不会违反单定义规则。

如果出于某种特殊的原因,需要某个常量的链接性为外部的,可以使用extern来修饰const常量,这将覆盖原来的const的内部链接性。

extern const int a = 0;

这种情况该变量与普通的外部链接性变量使用方法基本一致(除了他是常量),也就是必须在所有使用它的文件中使用extern声明他。

下述表格说明了与普通外部变量的区别

类型定义方法链接性其他文件的使用方法
常规外部变量在所有代码块外部定义外部链接性使用extern声明变量后使用
const外部变量(内部链接性)在所有代码块外部定义,且被const修饰内部链接性如果包含了声明const外部变量的头文件,可以直接使用。
const外部变量 (外部链接性)在所有代码块定义,且被const和extern同时修饰外部链接性同时使用extern和const变量引用变量,且引用常量只能在一处初始化。

,如果在代码块内部创建常量,只有在该代码块中常量可用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值