const和volatile

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了const和volatile相关的知识,希望对你有一定的参考价值。

对于const变量,人们有个误区,就是认为const是个常量,其实这种说法是不正确的,const本质还是一个变量,只是这个变量被const修饰后成为了只读的变量。

const只读变量

关于const有几点要注意的:

1.const修饰的变量是只读的,本质还是变量。

2.const修饰的局部变量在栈上分配空间。

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

4.const只在编译期有用,在运行期无用。


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


const全局变量的分歧

在现代C语言编译器中,修改const全局变量将导致程序崩溃(在现代C语言编译器中,被const修饰的全局变量被编译器存放在只读存储区,所以修改该变量将导致程序奔溃)

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


下面我们通过一个编程实验来验证一下。

技术分享图片

这是在BCC编译环境下的运行结果,BCC是一款标准C语言编译器,它将const修饰的全局变量存储于可以改变的全局数据区。所以当程序改变其中的变量的时候,不会报错。


技术分享图片

在linux系统中运行程序会出现段错误的提示,原因是因为gcc编译器是一款现代C语言编译器,全局变量i被const修饰后,被编译器存储在只读存储区,当视图修改的时候会报错。

技术分享图片

在函数中,局部变量i被static修饰后,成为全局变量,当用const修饰后,编译器将它储存在只读存储区。再次修改会出错。


技术分享图片

在linux中  局部变量i被const修饰后,gcc编译器将它存储在栈上,其值可以改变。程序不报错。


const的本质

1.C语言中的const使得变量具有只读属性。

2.现代C编译器中的const将具有全局生命周期的变量存储于只读存储区。

3.const本能定义真正意义上的常量。


const修饰函数参数和返回值

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

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

 Tips:

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

技术分享图片

技术分享图片

程序中有两处错误,第一处是j变量被static const修饰后 编译器将它存储在只读存储区,修改值会出现程序奔溃,第二处是全局变量g_array被const修饰也被编译器存储在只读存储区,修改值会发生程序奔溃。


深藏不露的volatile

1.volatile可以理解为编译器警告指示字;

2.volatile告诉编译器必须每次去内存中去变量值。

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

4.volatile也可以修饰可能被多个未知因数改变的变量。

技术分享图片


一个有趣的问题

const volatile int i=0;

-变量i具有什么样的特性?

-编译器如何处理这个变量?

i是一个只读变量,编译器不做任何优化,每次访问i的时候 都会让编译器去内存中去取值。


小结

  1. const使得变量具有只读属性

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

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

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

    技术分享图片


以上是关于const和volatile的主要内容,如果未能解决你的问题,请参考以下文章

Java 锁

Java 锁

volatile和synchronized 差别

C# 特性之volatile

关键字: volatile详解

1.7volatile关键字