const和volatile的讲解

const定义的变量
先看一段代码:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    const int n = 10;
    n = 20;     //可以赋值吗?
    printf("%d\n", n);
    system("pause");
    return 0;
}

这里写图片描述
可见const修饰的变量不能被改。

在c语言中,当const修饰一个标识符的时候,我们说,const依然是一个变量,只是它具有常属性,不能被改。

test.c

    const int n = 10;
    int arr[10];
    int arr2[n];//可以吗?

这里写图片描述
它不能用于表示数组的大小,可见const修饰的n是一个变量。

在c++中,const修饰的标识符就是常量
    const int n = 10;
    int arr[10];
    int arr2[n];//可以吗?

我们会发现编译时没有任何错误,
我们在来看一段代码:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    const int n = 10;
    int *p = (int *)&n;
    *p = 20;
    printf("%d\n", n);
    system("pause");
    return 0;
}

看看程序会输出什么?
这里写图片描述
我们看看内存中num的变化:
这里写图片描述
内存中的num已经变成了20,但为什么输出还是10呢?????
编译器在编译期间可能对代码进行优化。
当编译器看到这里的num被const修饰,从语义上讲这里的num是不期望被改变的,那优化的时候就可以把num的值存放到寄存器(用于提高访问效率)中。以后只要使用num的地方都去寄存器中取,那即使num对应的内存中的值发生变化,寄存器也是感知不到的,所以造成输出10的结果。


volatile
当我们对代码进行以下修改:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    volatile const int n = 10;
    int *p = (int *)&n;
    *p = 20;
    printf("%d\n", n);
    system("pause");
    return 0;
}

程序又会输出什么?
这里写图片描述
所以volatile起到了关键的作用。
volatile的作用:编译时不优化,执行时不缓存,每次需要从内存中读出(保证内存的可见性)。
使用场景:用于多线程或多CPU线程。

猜你喜欢

转载自blog.csdn.net/zhao_miao/article/details/80673961