文章目录
- const 关键字
- 修饰变量
- 修饰指针
- 修饰形参
- 修饰全局变量
- volatile关键字
- restrict关键字
- _Atomic关键字(c11)
const 关键字
修饰变量
将变量变为只读
const int nochange;
nochange = 4; //不允许
const int a = 5; //没问题
const int a[3] = {3, 5, 6};
a[0] = 4; //不允许
修饰指针
const 修饰指针变量有以下三种情况。
- const 修饰指针指向的内容,该指针指向的内容不可修改
int b = 30;
const int *q; // 使用声明一个指针,const修饰的是int型变量
//int const *q; 同上,仅写法区别
*q = 20; // 错误,不可以使用*q来修改值
q = &b; // 正确,指针指向的地址是可变的
- const 修饰指针,则指针为不可变量,指针指向的值可以改变,但是指针指向的地址不可变
int *const p; //声明一个指针,const修饰的是该指针
*p = 9; // 正确,可以修改该int值
int b = 7;
p = &b; // 错误, 不可以修改该指针指向的位置
- const 修饰指针和指针指向的内容,则指针指向地址和指针指向的内容都为不可变量。
const int *const p; //声明一个指针,const修饰的是该指针和该值
// int a = 4;
// const int *const p = &a; //可以初始化
*p = 9; // 错误,可以修改该int值
int b = 7;
p = &b; // 错误, 不可以修改该指针指向的位置
总结:const放在星号左边,表示修饰的是该值,如果放在星号右边则表示修饰的是该指针。
修饰形参
这是最常用的使用,这个其实和上面一样。
void Cpf(const int a)
{
a = 9; //错误,a 的值不能被改变
}
const修饰指针参数,同上面const修饰指针变量
void Cpf(int *const a , const int *c)
{
int b = 4;
//a = &b; 错误,指针不能被修改
*a = 9; //指针指向的值可以修改
//*c = 10; 错误,指针指向的值不可修改
c = &b; //指针指向的地址可以修改
}
void display(const int arr1[], const int *arr2); //参数1和参数二相同,都是不能修改数组的元素的值
修饰全局变量
我们知道有全局变量,如果任何人都能使用全局变量,那将非常危险。所以一般全局变量我们给他用const修饰作为只读的,用来保障安全。
那么有两种方式来实现:
- 在一个文件中定义,另一个文件中使用extern声明来使用。
- const修饰变量并用static修饰,放在一个头文件中。其他要使用的源文件包含该头文件。这里必须加static不然在不同文件中都包含就会出现重定义。
volatile关键字
https://blog.csdn.net/m0_62391199/article/details/123746218
volatile 关键字修饰的变量表示可以被某些编译器,未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
val1 = x;
val2 = x;
智能的编译器看到上面两个变量都使用了x,而并未改变该值,所以编译器把x临时存储在寄存器。val2赋值的时候,会直接从寄存器中读取x值而不是从内存中。
但是如果其他线程或者其他进程在两条语句之间修改了x的值,这时cpu就不知道该值改变还是从寄存器中读取,这读取的就是原值。
所以volatile关键字表示,每次都从内存中读取值,而不做优化,不暂存在寄存器中(和register变量做区分);
restrict关键字
_Atomic关键字(c11)
用于多线程,原子操作变量
当一个线程对一个原子变量对象执行原子操作的时候,其他线程不能访问该对象。
这里的赋值操作需要调用特定函数来实现。