zoukankan      html  css  js  c++  java
  • const修饰符限定的常量

    类型前加const修饰符限定变量为只读,称为常量,定义时必须初始化,且初始化后编译器不允许再修改常量的值。

    一、常量的定义##

    const在类型前面

    const int value;                  //value是const
    const char *value;                //*value是const, value可变
    const (char *) value;            //value是const,*value可变
    char* const value;               //value是const,*value可变
    const char* const value;     //value和*value都是const
    

    const在类型后面

    int const value;                // value是const
    char const * value;             // *value是const, value可变
    (char *) const value;          //value是const,*value可变
    char* const value;             // value是const,*value可变
    char const* const value;    // value和*value都是const
    

    总结
    const在(*)左侧指针所指的值不可改变,const在(*)右侧指针不可改变。

    二、常量(const)与变量(non-const)之间的转换##

    non-const转化为const

    int a = 10;
    const int b = const_case<const int>(a);
    

    const_case<const ([type])>(([data]))会返回non-const。
    一般不用,因为直接(int b = a)就好,因为(a)作为常量可以直接赋给变量

    const转化为non-const

    const int a = 10;
    int b = const_cast<int>(a);
    

    const_cast<([type])>(([data]))可用于去除const。

    三、常量(const)与变量(non-const)之间的赋值##

    1.常量在初始化后就不可以再被赋值。###

    2.常量赋值给变量###

    一般的常量赋值给变量没有问题,但指针所指的值为const时要利用变换const_cast去const限定。
    可以理解为指针所指的值限定为const时,编译器限定该地址下所存的为常量只读,而赋给普通指针时,普通指针默认改地址下存的为变量可以被更改。然而同一地址下不可能即为常量又为变量,所以报错。

    const int a = 10;
    int b = a;                //正确
    const int* c = &a;
    int *d = c;              //报错
    int *e = const_cast<int*> (c); //正确
    

    注:此时通过e来更改地址下所存的数据,c的值也会被更改,但会出现如下现象:

        const int c = 10;
        int *e = const_cast<int*> (&c); 
        (*e)++;
    
        cout << "c address= " << &c << endl;
        cout << "e adderss= " << e << endl;
        cout << "c value= " << c << endl;;
        cout << "e value= " << *e << endl;
    
    //输出为
    //    c address= 0x7ffde623acb4
    //    e adderss= 0x7ffde623acb4
    //    c value= 10
    //    e value= 11
    

    虽然地址相同但却存着不同的值,猜想可能的原因在于编译器进行了优化,由于寄存器访问的速度远远超过内存访问速度,因此编译器会将部分数据存储在寄存器中,需要时直接从寄存器中取出。本题数据类型为const,编译器认为数据不会被修改,因此放心大胆从寄存器中取值了,但是事实上内存中的数据已经被修改了。
    如何来验证上面的猜测呢,当然是禁止编译器优化了,可以使用volatile关键字禁止编译器的优化,这样编译器每次都不得不从内存中取数据,这样在内存中数据被修改后就会相应修改了。

        volatile const int c = 10;
        int *e = const_cast<int*> (&c);
        (*e)++;
    
        cout << "c address= " << &c << endl;
        cout << "e adderss= " << e << endl;
        cout << "c value= " << c << endl;;
        cout << "e value= " << *e << endl;
    
    //输出为
    //    c address= 1
    //    e adderss= 0x7ffd2e357204
    //    c value= 11
    //    e value= 11
    

    可以看到值变为相同的了,但地址变为1了,小生也不知道为什么(:

  • 相关阅读:
    对List 集合中元素进行排序
    webSocket 中使用 @Autowired 注入对应为null
    警告:添加非被动事件侦听器到滚动阻塞'touchstart'事件(Added non-passive event listener to a scroll-blocking 'touchstart' event. Consider marking event han)
    在webpack中使用monaco-editor
    vue下使用Monaco Editor
    前端开发Docker快速入门(二)制作镜像并创建容器
    微信开放平台-第三方平台代小程序实现业务
    微信开放平台-第三方平台授权流程及接口概述
    MyBatis实现动态排序方法
    IDEA中下载Git项目时输错密码的解决方法
  • 原文地址:https://www.cnblogs.com/narjaja/p/9275805.html
Copyright © 2011-2022 走看看