• C语言知识整理(2):volatile与register


    1.volatile

      volatile是易变的,不稳定的意思,volatile是关键字,是一种类型修饰符,用它修饰的变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其他线程等,遇到这个关键字声明的变量,编译器对访问该变量的代码不在进行优化,从而可以提供对特殊地址的稳定访问。那么什么是编译器优化呢?

      为了提高运行效率,攻城湿们可是费尽心机地把代码优化,把程序运行时存取速度优化。一般,分为硬件优化软件优化。硬件优化,流水线工作,详细可以参考《计算机组成原理》。软件优化,一部分是程序猿们做的代码优化(前提你得有优化的思路和能力),还有一部分就是我们的编译器优化了。现代的编译器经过那么多年的发展,已经比较成熟,把很多余的变量忽略掉,让代码的效率更高。而在默认情况下,编译器都会对代码进行优化,为了提高存取变量的速度,会把一些变量在寄存器(要知道控制器、运算器和寄存器是CPU的三大组成成分)里存取,而不是在内存里存取了,那这样CPU在自己家里拿东西当然比从内存那里拿东西要快得多。举个小栗子:

        int i = 5;
        int a = i;
        ……
        int b = i;
      编译器发现两次从i读数据的代码之间,并没有对i进行过操作,它会自动把上次读的数据放在b中,而不是重新从i里面读取。

      而volatile 关键字告诉编译器该变量是随时可能发生变化的,每次使用它的时候必须从内存中取出他的值,因而编译器生成的汇编代码会从原内存地址中读取数据使用,而不是从寄存器或者缓存中读取,从而保证了对特殊地址的稳定访问。也就是说,状态要经常变化的,为了防止我们编译优化而导致的存取的数据不同步的问题,这时我们就需要用到!那具体到什么场景下需要用到volatile关键字呢?

      1、并行设备的硬件寄存器(如:状态寄存器);

      2、一个中断服务子程序中会访问到的非自动变量(Non-automatic variables);

      3、多线程应用中被几个任务共享的变量

      上面提到了非自动变量,这里就进一步对几种变量做一番解释:

      自动变量:是在函数内部定义和使用的变量,它是局部变量

      非自动变量:有两种,一种是全局变量,一种是静态变量

      全局变量:在函数外面定义的变量,只能定义一次,不能有重复的定义,不然就会发生错误,而其他的文件要想使用这个变量,需要extern来声明这个变量(也可省略,因为默认就是extern),这个声明叫做引用声明。若不想被其他文件访问,则用static关键字声明为静态变量。静态变量与自动变量的本质区别是,静态变量并不像自动变量那样使用堆栈机制来使用内存。而是为静态变量分配固定的内存,在程序运行的整个过程中,它都会被保持,而不会不销毁。这就是说静态变量的持续性是程序运行的整个周期。这有利于我们共享一些数据。如果静态变量在函数内部定义,则它的作用域就是在这个函数内部,仅在这个函数内部使用它才有效,但是它不同于自动变量的,自动变量离开函数后就会别销毁,而静态变量不会被销毁。他在函数的整个运行周期内都会存在。

    2.register

      这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率。注意是尽可能,不是绝对。你想想,一个CPU 的寄存器也就那么几个或几十个,你要是定义了很多很多register 变量,它累死也可能不能全部把这些变量放入寄存器吧。

  • 相关阅读:
    清空收缩数据库日志文件的方法
    JavaScript中的剪贴板的使用(clipboardData)
    location.search在客户端获取Url参数的方法
    JS之onkeypress,onkeydown,onkeyup区别
    网页中的meta标签的作用
    SQL优化条
    JS简洁经典滚动上下与左右
    结构体
    static修饰符
    Solaris内存监控 & solaris查看内存使用情况
  • 原文地址:https://www.cnblogs.com/yif1991/p/5028311.html
Copyright © 2020-2023  润新知