【C++深度解析】9、const 常量?只读变量?

倖福魔咒の 提交于 2020-01-27 18:54:20


看了前面的关于 const 的内容,不知道是不是有疑问,const 什么时候为只读变量,什么时候是常量?

1 const 常量的判别准则

  • 只有用字面量初始化的 const 常量才会进入符号表
  • 使用其他变量初始化的 const 常量仍然是只读变量
  • volatile 修饰的 const 常量不会进入符号表

综上所述,在编译期间不能直接确定初始值的 const 标示符,都被作为只读变量处理。

const 引用的类型与初始化变量的类型

  • 相同:初始化变量成为只读变量
  • 不同:生成一个新的只读变量

1.1 编程实验

// 9-1.c
#include<stdio.h>
int main()
{
    const int x = 1;
    const int& rx = x;
    int& nrx = const_cast<int&>(rx);
    nrx = 5;
    printf("x = %d\n", x);
    printf("rx = %d\n", rx);
    printf("nrx = %d\n", nrx);
    printf("&x = %p\n", &x);
    printf("&rx = %p\n", &rx);
    printf("&nrx = %p\n", &nrx);

    volatile const int y = 2;
    int* p = const_cast<int*>(&y);
    *p = 6;
    printf("y = %d\n", y);
    printf("p = %p\n", p);

    const int z = y;
    p = const_cast<int*>(&z);
    *p = 7;
    printf("z = %d\n", z);
    printf("p = %p\n", p);

    char c = 'c';
    char& rc = c;
    const int& trc = c;
    rc = 'a';
    printf("c = %c\n", c);
    printf("rc = %c\n", rc);
    printf("trc = %c\n", trc);
    return 0;
}
  • 程序第 5-8 行,x 通过字面量初始化,是常量,存储在符号表中;rx 通过变量 x 初始化,不能在编译器确定初始值,是只读变量;nrx 通过 const_cast 去掉了只读属性。修改nrx 修改的是内存的值,不能修改符号表中的值,所以 x 值不变,rx 和 nrx 值修改为 5。rx 是 x 的引用,nrx 是 rx 的引用,所以三者的地址是相同的。
  • 第 16-18 行,变量 y 被 volatile 修饰,是只读变量,指针 p 使用 const_cast 去除其只读属性,并指向变量 y,修改指针 p 指向的值也就是修改了内存,y 变为 6。
  • 第 22- 24 行,const 修饰的 z 通过变量 y 初始化,具有只读属性,指针 p 通过const_cast 去除其只读属性,并指向 z,修改 *p 也就是修改了内存值,所以 z 被修改为 7。
  • 第 28-30 行,trc 为 const int 型的引用,c 为 char 变量,类型不同,trc 生成一个新的只读变量,所以修改 rc 会 改变 c 的值,但是不影响 trc。

编译运行:

$ g++ 9-1.c -o 9-1
$ ./9-1
x = 1
rx = 5
nrx = 5
&x = 0x7ffee6ed4440
&rx = 0x7ffee6ed4440
&nrx = 0x7ffee6ed4440
y = 6
p = 0x7ffee6ed4444
z = 7
p = 0x7ffee6ed4448
c = a
rc = a
trc = c

当 const 修饰的变量是只读变量时,仅仅是说明不能通过这个只读变量修改内存的值,但是可以通过其他方法修改内存值。

2 小结

1、const 引用能够生成新的只读变量
2、编译时不能直接确定初始值的 const 标示符都是只读变量

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!