发布时间:2020-09-29 08:58 原文链接: C语言之const和volatile究极学习(二)

输出结果:

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 <stdio.h>
const char*fun(const int i)

  i=8;
   return "TXP";

int main()

  const char * p=fun(0);
   printf("%s",p);
   p[1]='_';
   printf("%s",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 <stdio.h>
const char*fun(const int i)

//   i=8;
   return "TXP";

int main()

  const char * p=fun(0);
   printf("%s",p);
 //  p[1]='_';
  // printf("%s",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 <stdio.h>
int main()

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

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

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

总之一句话:上面的结论中,volatile修饰的都是变量,变量就可能改变,不会被编译器优化;只是说我们上面的结论应用场景不同而已。

三、总结

const使得变量具有只读属性

const不能定义真正意义上的常量

const将具有全局生命周期的变量存储于只读存储区

volatile强制编译器减少优化,必须每次从内存中取值