C/C++:CV(const 与 volatile)属性的理解

C/C++提供多种声明变量和函数存储持续性、作用域和链接性的关键字,有些被称为存储说明符(store class specifier)或 cv 限定符(cv-qualifier), cv 限定符可出现于任何类型说明符(包括声明文法的 声明说明符序列)中,以指定被声明对象或被命名类型的常量性(constness)或易变性(volatility)。

  • const ——定义类型为常量。
  • volatile ——定义类型为易变。

const用途:

  1. 声明符号常量,在声明符号常量的同时必须进行初始化,否则就没有机会再给符号常量赋值了。如果在声明符号常量时没有初始化,那么该常量的值将是不确定的,且无法修改!例如:
const int months = 12;
const bool flag=true;
注意

在C语言中,用const修饰的变量,其本质上还是个变量,只是它不允许作为左值存在,也就是不应该对该变量进行直接赋值修改该变量,但是这不意味着该变量的值就无法修改。我们可以通过指针来修改该变量的值:

#include <stdio.h>
int main()
{
	const int a = 5;
	int* p = (int*)&a;
	
	printf("a = %d\n",a); //5
	
	*p = 10;
	printf("a = %d\n",a); //10
	return 0;
}

但是在C++中,执行的结果都是5,因为在C++编译的过程,当碰到用const修饰的变量时,编译器是直接将变量的值和变量的符号对应起来一起存到符号表中,例如const int a = 5;在符号表中就会将a和5对应起来,在编译的过程中,当碰到printf(“a = %d\n”,a); 时,为用 5 直接将 a 替换掉。在C++中,编译器不会为a分配存储空间,在C语言中就会为a分配存储空间,所以在C编译器中,就可以通过指针来改变用const修饰的变量。如果对const常量使用了extern或者取地址符&。C++会为常量分配存储空间,但是却不会使用该存储空间中的值。所以C++中的 const 更像编译阶段的 #define,但是const可以指明类型,也可以用于数组

  1. 修饰常量的作用域和链接性。(C++)
  • C和C++中全局 const 变量的作用域相同,都是当前文件,但是它们的可见范围不同:C语言中 const 全局变量的可见范围是整个程序,在其他文件中使用 extern 声明后就可以使用;而C++中 const 全局变量的可见范围仅限于当前文件,在其他文件中不可见,所以它可以定义在头文件中,多次引入后也不会出错。

注意:在C++中,可以使用extern关键字来增大 C++ 全局 const 变量的可见范围:extern const int time = 1;这样在一个文件中声明的常量time就可以在另外一个文件中使用,需要注意的是其他文件中使用time时必须使用extern:extern int time;因为time在多个文件中共享,所以只能有一个文件对其进行初始化!

volatile用途

改善编译器的优化能力。volatile 影响编译器编译的结果,volatile指出 变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化,以免出错,(VC++ 在产生release版可执行码时会 进行编译优化,加volatile关键字的变量有关的运算,将不进行编译优化。)当要求使用 volatile 声明的变量的值的时候,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据。而且读取的数据立刻被保存。

volatile int i=10;
int a = i;
...
// 其他代码,并未明确告诉编译器,对 i 进行过操作
int b = i;

volatile 指出 i 是随时可能发生变化的,每次使用它的时候必须从 i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在 b 中。而优化做法是,由于编译器发现两次从 i读数据的代码之间的代码没有对 i 进行过操作,它会自动把上次读的数据放在 b 中。而不是重新从 i 里面读。这样以来,如果 i是一个寄存器变量或者表示一个端口数据就容易出错,所以说 volatile 可以保证对特殊地址的稳定访问。

  • 16
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值