热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C语言的const和volatile怎么使用

本篇内容主要讲解“C语言的const和volatile怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“

本篇内容主要讲解“C语言的const和volatile怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C语言的const和volatile怎么使用”吧!

一、const的用法:

1、const只读变量:

  • const修饰的变量是只读的,本质上还是变量

  • const修饰的局部变量在栈上分配空间

  • const修饰的全局变量在全局数据区分配空间

  • const只在编译期有用,在运行期没有用

注:const修饰的变量不是真的常量,它只是告诉编译器该变量不能出现在赋值符号的左边

2、const全局变量的分歧:

  • 在现代c语言编译器中,修改const全局变量将导致程序崩溃

  • 标准c语言编译器不会将const修饰的全局变量存储于只读存储区中,而是存储于可修改的全局数据区,其值依然可以改变

3、代码示例:

(1)只读变量代码示例:

#include 

int main()
{
   const int a =10;
   printf("a = %d\n",a);

   a=20;
   printf("a = %d\n",a);
  
  return 0;
}
 

运行结果:

test.c: In function ‘main’:
test.c:8:4: error: assignment of read-only variable ‘a’
    a=20;
    ^
 

注解:显示这个结果很正常,变量a被const修饰了,它就成了只读的。

(2)如果对变量a的值进行修改:

#include 

int main()
{
   const int a =10;
   int *p =(int *) &a;
   printf("a = %d\n",a);

   *p=20;
   printf("a = %d\n",a);


  return 0;
}

 

运行结果:

root@txp-virtual-machine:/home/txp# ./a.out
a = 10
a = 20

 

注解:通过指针的方式,就能够把a的值进行修改,这也论证了“const修饰的变量是只读的,本质上还是变量”这句话

(3)const修饰全局变量:

代码版本一

#include 
const int b = 40;

int main()
{
   
 
   printf("b = %d\n",b);
   b=20;
   printf("b = %d\n",b);


  return 0;
}

输出结果:

root@txp-virtual-machine:/home/txp# gcc test.c
test.c: In function ‘main’:
test.c:10:4: error: assignment of read-only variable ‘b’
    b=20;
    ^

注解:跟const修饰栈上的变量用法一样

代码版本二

#include 
const int b = 40;

int main()
{

   int *p =(int *) &b;
   printf("b = %d\n",b);

   *p=20;
   printf("b = %d\n",b);


  return 0;
}
 

运行结果:

root@txp-virtual-machine:/home/txp# ./a.out
b = 40
Segmentation fault (core dumped)
 

注解:这里出现了段错误,这也验证了我们上面所说的“修改const全局变量将导致程序崩溃”。

同时为了验证“标准c语言编译器不会将const修饰的全局变量存储于只读存储区中,而是存储于可修改的全局数据区,其值依然可以改变”这句话,我把这段代码放到dev c++上进行试验:

C语言的const和volatile怎么使用  

说明:我这个版本的编译器支持标准c语言,所以没导致程序崩溃,能够正常运行

4、const的本质

  • c语言中的const使得变量具有只读属性

  • 现代c编译器中的const将具有全局生命周期的变量存储于只读存储区,不是放在全局数据区

注:const不能定义真正意义上的常量;同时这里注意static关键字修饰的变量,它的生命周期和全局变量一样。

代码示例:

#include 

const int Array[5] = {0};

void fun(int *p,int v)
{
   *p=v;
}
int main()
{
    int const i =1;
    const static int j =2;
    int const array[5] = {0};

    fun((int *)&i,1);
    fun((int *)&j,2);
    fun((int *)&array[2],3);
    fun((int *)&Array[1],4);

   return 0;

}
 

输出结果:

root@txp-virtual-machine:/home/txp# ./a.out
Segmentation fault (core dumped)
 

注解:这里会有段错误,错误出现在const+static修饰的j变量对其进行修改,还有const修饰的全局数组。

5、const修饰函数参数和返回值

  • const修饰函数参数表示在函数体内不希望改变参数的值

  • const修饰函数返回值表示返回值不可改变,多用于返回指针的情形

在c语言中的字符串字面量存储于只读存储区中,在程序中需要使用const char* 指针,例如:

const char * s = "TXP嵌入式";//字符串字面量
 

代码示例:

#include 

const char*fun(const int i)
{
   i=8;
    return "TXP";
}
int main()
{
   const char * p=fun(0);
    printf("%s\n",p);
    p[1]='_';
    printf("%s\n",p);

    return 0;


}

 

输出结果:

root@txp-virtual-machine:/home/txp# gcc test.c
test.c: In function ‘fun’:
test.c:5:4: error: assignment of read-only parameter ‘i’
    i=8;
    ^
test.c: In function ‘main’:
test.c:12:5: error: assignment of read-only location ‘*(p + 1u)’
     p[1]='_';
     ^
 

注解:上面这样写,肯定有问题。

代码进化:

#include 

const char*fun(const int i)
{
//   i=8;
    return "TXP";
}
int main()
{
   const char * p=fun(0);
    printf("%s\n",p);
  //  p[1]='_';
   // printf("%s\n",p);

    return 0;


}
 

输出结果:

root@txp-virtual-machine:/home/txp# ./a.out
TXP
 

二、volatile的用法

老实说,这个关键字在面试题目里面经常会出现,但是平时学习的时候,如果你没有真正理解这其中的含义,在笔试的时候,脑袋里面可能依稀是记得有那么几个结论,但是有时候吧,一紧张就把结论给忘了,也不是不可能,所以说,咋们还是老实一点,得真正把它原理搞明白才行,这样上来战场就不怕了,以后写代码也就少一点bug。

1、volatile的常用结论(volatile英文本意就是易变的意思)

这里我先给结论,然后再给一个例子,把这个例子的讲明白,所有结论就都明白了。

  • volatile可理解为“编译器警告指示字”

  • volatile告诉编译器必须每次去内存中取变量值

  • volatile主要修饰可能被多个线程访问的变量

  • volatile也可以修饰可能被未知因素更改的变量

  • volatile可以修饰一个中断子程序中会访问到的非自动变量

2、分析原理

大家可能平时在博客学习,都会发现讲解编译器优化的,然后加了volatile关键来修饰变量,就告诉编译器不要去优化这个变量了,那么这里的优化到底是什么意思呢?

从字面上来理解优化两个字,意思就是最优值(变量的值不会改变),这里我用一个简单代码来说明一下:

#include 

int main()
{
    int a =1;//volatile int a =0;
     
    while(a)
    {
    
    }
}

说明:上面的代码,如果变量a没有加volatile修饰的话,编译器就会优化它(也就是a的值一直不变),所以while就一直死循环;然后我如果加了volatile来修饰的话,编译器就不会去优化变量a,不优化的意思就是说,变量a的值可能就会改变,while就不会一直死循环。

当然这里为了好理解,我说的不是很专业,没有从寄存器和内存的角度去说。(我也不想那么去讲解,简单理解了就行)

到此,相信大家对“C语言的const和volatile怎么使用”有了更深的了解,不妨来实际操作一番吧!这里是编程笔记网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • C++中的三角函数计算及其应用
    本文介绍了C++中的三角函数的计算方法和应用,包括计算余弦、正弦、正切值以及反三角函数求对应的弧度制角度的示例代码。代码中使用了C++的数学库和命名空间,通过赋值和输出语句实现了三角函数的计算和结果显示。通过学习本文,读者可以了解到C++中三角函数的基本用法和应用场景。 ... [详细]
author-avatar
ggty11
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有