1、extern:
声明一个变量,extern声明的变量没有建立存储空间。
extern int a ; //变量在定义的时候创建存储空间。
①当我们在编译器中试图运行以下代码,系统会报错。
错误原因是“无法解析外部符号_a”.系统认为变量a是没有开辟内存空间的,不能进行存储。
所以,extern声明有a变量,但不是定义变量a,不会为变量a开辟存储空间。
2、const:
定义一个常量,常量的值不能修改。
const int a = 10;
①如下代码,若先定义一个不可变的整型变量a并赋值为10,则再次给a赋新值时,系统会在变量a下面标红,鼠标放在标红处会提示出错原因(如下图)。
②强行运行以上代码后
3、Volatile:
防止编译器优化代码
(1)①先定义一个普通的整型变量 a,然后分别进行3次赋值。众所周知,前两次赋值会被最后一次赋值覆盖掉,所以前两次的赋值已经无意义了,可以被优化掉。
代码
②通过编译
编译过程
③生成汇编语言。通过查看汇编结果,可以看出3次赋值均被优化掉了,为什么最后一次赋值也被优化了呢?这是因为,我们的C语言代码对变量a进行三次赋值后,并没有对a进行调用或后续其他任何操作,系统认为这三句都是无实际意义的,就被优化掉了哈哈哈。
(2)① 给a赋值的这3步,不想被优化可以使用volatile。在整型int 前加volatile即可。
②带优化选项的编译过程
③生成汇编语言。给a赋值的三步语句还在,并没有被优化掉。其他代码被正常简化了。
4、register:
定义寄存器变量,提高效率。register是建议型的指令,而不是命令型的指令,如果CPU有空闲寄存器,那么register就生效,如果没有空闲寄存器,那么register无效。
我们定义一个变量,想用更快的方式访问这个变量,就可以用register。
cpu访问内存需要经过总线,时间比较长。定义了一个变量,这个变量就使用寄存器,不经过内存也不需要访问总线,那么访问速度自然就很快。
(1)①一般的不加register的变量类型,是往内存栈(%rsp)中去赋值。
②经过编译成汇编代码,语句如下。
(2)①加register的变量类型,是往寄存器(%eax)中去赋值。
②经过编译成汇编代码,语句如下。
寄存器的名字,了解即可。
寄存器、缓存、内存三者关系
按与 CPU 远近来分,离得最近的是寄存器,然后缓存(CPU 缓存),最后内存。
CPU 计算时,先预先把要用的数据从硬盘读到内存,然后再把即将要用的数据读到寄存器。于是 CPU <---> 寄存器 <--->内存,这就是它们之间的信息交换。
那为什么有缓存呢?因为如果经常操作内存中的同一地址的数据,就会影响速度。于是就在寄存器与内存之间设置一个缓存。
因为从缓存提取的速度远高于内存。当然缓存的价格肯定远远高于内存,不然的话,机器里就没有内存的存在。
5、总结
关注公粽号@李桥桉,可免费获取配套《C语言讲义》,知识点超全超系统哦!非常适合C语言入门及、进阶选手学习哦。