10 问题分析一

1 const

  • 问题:const 所修饰的标识符,什么时候为只读变量,什么时候是常量

  • const 常量的判别准则

    • 只有用字面量初始化的 const 常量才会进入符号表
    • 使用其他变量初始化的 const 常量仍然是只读变量
    • volatile 修饰的 const 常量不会进入符号表
    • 编译期间不能直接确定初始值const 标识符,都被作为只读变量处理
  • const 引用的类型与初始化变量的类型

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

    • Demo

      #include <stdio.h>
      
      int main()
      {
          const int x = 1;  //x进入符号表
          const int& rx = x;  //rx代表一个只读变量
          
          int& nrx = const_cast<int&>(rx);  //消除只读变量rx的只读属性
          
          nrx = 5;
          
          printf("x = %d
      ", x);  //1
          printf("rx = %d
      ", rx);  //5
          printf("nrx = %d
      ", nrx);  //5
          printf("&x = %p
      ", &x);  //&x = 0xbfa2bdf8
          printf("&rx = %p
      ", &rx);  //&rx = 0xbfa2bdf8
          printf("&nrx = %p
      ", &nrx);  //&nrx = 0xbfa2bdf8
          
          volatile const int y = 2;  //只读变量
          int* p = const_cast<int*>(&y);
          
          *p = 6;
          
          printf("y = %d
      ", y);  //6
          printf("p = %p
      ", p);  //p = 0xbfa2bdec
          
          const int z = y;  //只读变量
          
          p = const_cast<int*>(&z);
          
          *p = 7;
          
          printf("z = %d
      ", z);  //7
          printf("p = %p
      ", p);  //p = 0xbfa2bde4
          
          char c = 'c';
          char& rc = c;
          const int& trc = c;  //引用类型不同:生成一个新的只读变量trc
          
          rc = 'a';  //改变rc与trc无关
          
          printf("c = %c
      ", c);  //a
          printf("rc = %c
      ", rc);  //a
          printf("trc = %c
      ", trc);  //c
          
          return 0;
      }
      
    • 编译运行

      x = 1
      rx = 5
      nrx = 5
      &x = 0xbfa2bdf8
      &rx = 0xbfa2bdf8
      &nrx = 0xbfa2bdf8
      y = 6
      p = 0xbfa2bdec
      z = 7
      p = 0xbfa2bde4
      c = a
      rc = a
      trc = c
      

2 引用

  • 问题:引用与指针有什么关系?如何理解“引用的本质是指针常量”?

  • 指针是一个变量

    • 值为一个内存地址,不需要初始化,可以保存不同的地址
    • 通过指针可以访问对应内存地址中的值
    • 指针可以被 const 修饰成为常量或者只读变量
  • 引用只是一个变量的新名字

    • 对引用的操作(赋值,取地址等)都会传递到代表的变量上
    • const 引用使其代表的变量具有只读属性
    • 引用必须在定义时初始化,之后无法代表其它变量
  • 使用 C++ 语言的角度来看

    • 引用与指针没有任何的关系
    • 引用是变量的新名字,操作引用就是操作对应的变量
  • 从 C++ 编译器的角度来看

    • 为了支持新概念“引用”,必须要一个有效的解决方案
    • 在编译器内部,使用指针常量实现“引用”
    • 因此,“引用”在定义时必须初始化
  • 在工程项目开发中

    • 当进行 C++编程时,直接站在使用的角度看待引用,与指针毫无关系,引用就是变量的别名

    • 当对 C++ 代码进行调试分析时,一些特殊情况,可以考虑站在 C++ 编译器的角度看待引用

    • 下面的代码有问题么?

      int a = 1;
      int b = 2;
      int* pc = new int(3);
      int& array[] = {a,b,*pc};
      
  • 示例

    • Demo

      #include <stdio.h>
      
      int a = 1;  //全局变量:静态存储区
      
      struct SV
      {
          int& x;
          int& y;
          int& z;
      };
      
      int main()
      {
          int b = 2;  //局部变量:栈
          int* pc = new int(3);  //局部变量;堆
          SV sv = {a, b, *pc};
          int& array[] = {a, b, *pc}; // &array[1] - &array[0] = ?  Expected ==> 4
          
          printf("&sv.x = %p
      ", &sv.x);  //&sv.x = 0x804a020
          printf("&sv.y = %p
      ", &sv.y);  //&sv.y = 0xbfc5093c
          printf("&sv.z = %p
      ", &sv.z);  //&sv.z = 0x994e008
          
          delete pc;
          
          return 0;
      }
      
    • 编译

      test.cpp: In function ‘int main()’:
      test.cpp:17: error: declaration of ‘array’ as array of references
      
    • 分析:array 引用数组破坏了数组地址应该是连续的规则 **=> C++ 中不支持引用数组

原文地址:https://www.cnblogs.com/bky-hbq/p/13709478.html