一、const
const修饰的变量是常变量,是不期望被修改的变量。我们如果要对它直接进行修改,程序编译时就会报错。可是,这个变量是可以被间接修改的:
#include <stdio.h>
#include <stdlib.h>
int main()
{
const int a = 10;
int *tmp = (int *)&a;
*tmp = 20; //通过地址访问这个变量就可以修改掉它
printf("a=%d\n", a);
return;
}
可是当我们对这段代码进行二级优化编译时,就会发现打印出来的值并没有被改变,这是为什么呢?
编译器在编译代码时会对代码进行优化,这时候由于被const修饰的变量是不期望被改变的变量,于是在优化时为了提高运行效率,可能会吧这个变量优化进寄存器,从寄存器中读取数据;而我们修改这个变量时修改的是内存中的。当我们打印时,CPU从寄存器中取的变量并没有改变。
二、volatile
上面写的const修饰的变量在编译时可能会优化进寄存器中而造成的问题,可以在const前面加上关键字volatile来解决。
#include <stdio.h>
#include <stdlib.h>
int main()
{
volatile const int a = 10;
int *tmp = (int *)&a;
*tmp = 20;
printf("a=%d\n", a);
return;
}
这个关键字的作用是让编译器在编译时不优化,执行时不缓存,每次从内存中读取(保证内存的可见性)。
三、static
1、static修饰的变量可以多次赋值,但不能重复初始化。
#include <stdio.h>
#include <stdlib.h>
static int a;
void fun1()
{
a = 0;
a++;
printf("a=%d\n",a);
}
void fun2()
{
static b = 0;
b++;
printf("b=%d\n",b);
}
int main()
{
int i = 0;
for(; i < 10; i++)
{
fun1();
}
for(i = 0; i < 10; i++)
{
fun2();
}
return;
}
2、static修饰全局变量和函数时,该变量和函数只能在文件内部使用,不能被文件外调用,改变了他们的连接属性;
3、static修饰局部变量时,改变了它的存储类型和生命周期(是变量存储在静态区,不随函数调用的结束而消失),不改变其作用域和属性(变量还是只能在该函数内部使用)。