C语言中volatile关键字的深入讲解

 更新时间:2021年07月30日 11:24:22   作者:JeckXu666  
在程序设计中,尤其是在C语言、C++、C#和Java语言中,使用volatile关键字声明的变量或对象通常具有与优化、多线程相关的特殊属性,这篇文章主要给大家介绍了关于C语言volatile关键字的相关资料,需要的朋友可以参考下

1. 什么是volatile关键字?

volatile用于声明一个变量,告诉编译器该变量值容易发生改变,在编译、读取、存储该变量的时候都不要做任何优化,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取存储数据,不做优化,在我们做嵌入式开发的时候,该关键字作用很大,因为有时变量地址有可能是系统的一个外设地址,他的值的变化并不在程序控制范围内,随时有可能变化,因此需要对他进行声明,每次读取或者存储直接对地址进行操作,而不经过其他中间商,下面我以一个例子来分析vilatile的作用:

2. GCC优化等级

在看例子前先了解一下GCC的优化概念,通常C语言的编译器使用的是GCC编译器,他有个以下几个等级的优化

  • -O0 :(默认):没有优化。
  • -O或-O1 :优化,但不要花费太多的时间。
  • -O2 :更积极地优化
  • -O3 :最积极地优化
  • -Ofast :最高级的优化
  • -Os : 优化代码大小
  • -Og :在尽量不干扰调试的情况下优化

开启不同的优化等级,程序编译后的结果就会发生一定的变化,而volatile就是在开启优化的情况下使用,保护变量不被优化

3.volatile声明变量测试

我们先写一段c程序

#include <stdio.h>
int main(void)
{
    volatile int i=0;
    i=1;
    i=2;
    i=3;
    printf("%d",i);
    return 0;
}

程序创建一个变量i,对i进行三次赋值,使用-O默认优化等级对代码进行编译,查看汇编结果,我们可以看到优化后,i=1和i=2被优化,没有生成之间汇编代码,直接取最后的值寻址赋值给i

当我们使用Volatile声明变量后

#include <stdio.h>
int main(void)
{
    volatile int i=0;
    i=1;
    i=2;
    i=3;
    printf("%d",i);
    return 0;
}

编译如下,可以看到变量i的每一个赋值都生成了汇编代码,没有被优化,每次赋值都重新寻址赋值

当我们使用volatile对一个映射到外部寄存器的地址进行声明后,如果像上面连续赋值来传数据给外部寄存器,使用volatile声明就可以保护指令不会被优化,程序实现正常功能,当然除了用于对寄存器的保护外,volatile有时也使用在多线程间共享变量的保护,如果不注意,编译器会认为变量只在当前函数使用而进行优化,在其他任务中进行的改变就变的无效;如果中断中改变一个状态变量给其他函数进行检测,如果没有加volatile进行声明,也可以会因为编译器的优化而无效,所以大家在以上三种情况下使用变量时可以结合编译器的优化等级考虑一下,是不是需要将变量声明一下volatile关键字!!!

总结

到此这篇关于C语言中volatile关键字的文章就介绍到这了,更多相关C语言volatile关键字内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++继承介绍

    C++继承介绍

    C++继承可以是单一继承或多重继承,每一个继承连接可以是public,protected,private也可以是virtual或non-virtual
    2013-01-01
  • C语言--数字交换题目详解

    C语言--数字交换题目详解

    本文通过代码给大家介绍c语言数字交换的题目,通过实例代码给大家讲解的很详细,具有一定的参考借鉴价值,对c语言感兴趣的朋友一起看看吧
    2021-08-08
  • C语言入门篇--关键字static详解

    C语言入门篇--关键字static详解

    本篇文章是C语言系列基础篇,C语言中,static是用来修饰变量和函数:1.修饰局部变量–>静态局部变量2.修饰全局变量–>静态全局变量3.修饰函数–>静态函数
    2021-08-08
  • C/C++字符串查找函数全面了解

    C/C++字符串查找函数全面了解

    下面小编就为大家带来一篇C/C++字符串查找函数全面了解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • 利用C++实现一个线程安全的map

    利用C++实现一个线程安全的map

    这篇文章主要为大家详细介绍了如何利用C++实现一个线程安全的map(使用ChatCPT生成),代码是通过两轮对话完善的,感兴趣的小伙伴可以了解一下
    2023-05-05
  • C语言指针和数组深入探究使用方法

    C语言指针和数组深入探究使用方法

    在C语言和C++等语言中,数组元素全为指针变量的数组称为指针数组,指针数组中的元素都必须具有相同的存储类型、指向相同数据类型的指针变量。指针数组比较适合用来指向若干个字符串,使字符串处理更加方便、灵活
    2022-08-08
  • 如何配置 Sublime Text4为 C++ 编辑器

    如何配置 Sublime Text4为 C++ 编辑器

    这篇文章主要介绍了配置Sublime Text4为C++编辑器,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • C语言入门篇--初识C语言及数据类型

    C语言入门篇--初识C语言及数据类型

    本篇文章是c语言基础篇,主要为大家介绍了C语言的基本类型,为大家介绍了什么是C语言,希望可以帮助大家快速入门c语言的世界,更好的理解c语言
    2021-08-08
  • VC运用OPENGL加载BMP纹理图的实现方法汇总

    VC运用OPENGL加载BMP纹理图的实现方法汇总

    这篇文章主要介绍了VC运用OPENGL加载BMP纹理图的实现方法,对于更好的了解OpenGL很有帮助,需要的朋友可以参考下
    2014-07-07
  • C++利用easyx图形库实现创意天天酷跑小游戏

    C++利用easyx图形库实现创意天天酷跑小游戏

    这篇文章主要为大家详细介绍了C++如何利用easyx图形库实现创意小游戏——天天酷跑,文中的示例代码讲解详细,快跟随小编一起了解一下吧
    2023-03-03

最新评论