2 C++ 进化后的 const

1 C语言中的 const

  • const 修饰的变量是只读的,本质上还是变量

  • const 修饰的局部变量上分配空间

  • const 修饰的全局变量只读存储区分配空间

  • const 只在预编译期有用,在运行期无用

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

  • C/C++ 中的 const

    • Demo1:test.c

      #include <stdio.h>
      
      int main()
      {
          const int c = 0;
          int* p = (int*)&c;
          
          printf("Begin...
      ");
          
          *p = 5;
          
          printf("c = %d
      ", c);
          
          printf("End...
      ");
          
          return 0;
      }
      
    • 运行结果

      Begin...
      c = 5
      End...
      
    • Demo2:test.cpp

      #include <stdio.h>
      
      int main()
      {
          const int c = 0;
          int* p = (int*)&c;
          
          printf("Begin...
      ");
          
          *p = 5;
          
          printf("c = %d
      ", c);
          
          printf("*p = %d
      ",*p);
          
          printf("End...
      ");
          
          return 0;
      }
      
    • 运行结果:*为什么 c = 0,而 p = 5?

      Begin...
      c = 0
      *p = 5
      End...
      

2 C++ 中的 const

  • C++ 在 C 的基础上对 const 进行了进化处理

    • 当碰到 const 声明时在符号表中放入常量

    • 编译过程中若发现使用常量则直接以符号表中的值替换

    • 编译过程中若发现下述情况则给对应的常量分配存储空间

      • const 常量使用了 extern
      • const 常量使用 & 操作符
    • 注意:C++ 编译器虽然可能为 const 常量分配空间,但不会使用其存储空间中的值

    const int c = 0;  //将常量C存入符号表(c-0)
    int* p = (int*)&c;  //为c常量分配空间,但不使用
        
    printf("Begin...
    ");
        
    *p = 5;  //改变的是编译器为常量c分配的空间,所以p指向的空间也就是常量c所对应的空间里面的值变为5
        
    printf("c = %d
    ", c);  //用符号表中的值替换c(c-0)
        
    printf("End...
    ");
    
  • 存储空间对比

    • C语言中的 const 变量

      • C语言中的 const 变量是只读变量,会分配空间
    • C++ 中的 const 常量

      • 可能会分配空间
        • const 常量为全局,并且需要在其他文件中使用
        • 当使用 & 操作符对 const 常量取地址
  • C++ 中的 const 常量类似于宏定义

    const int c = 5; ≈ #define c 5
    

    但C++ 中的 const 常量与宏定义不同

    • const 常量是由编译器处理
    • 编译器对 const 常量进行类型检查作用域检查
    • 宏定义由预处理器处理,单纯的文本替换
  • const 与宏

    • Demo

      //test.c
      #include <stdio.h>
      
      void f()
      {
          #define a 3
          const int b = 4;
      }
      
      void g()
      {
          printf("a = %d
      ", a);
          //printf("b = %d
      ", b);
      }
      
      int main()
      {
          const int A = 1;
          const int B = 2;
          int array[A + B] = {0};
          int i = 0;
          
          for(i=0; i<(A + B); i++)
          {
              printf("array[%d] = %d
      ", i, array[i]);
          }
          
          f();
          g();
          
          return 0;
      }
      
    • 编译

      • AB 在c语言文件中是变量,两个变量相加的结果需要在运行时才能确定,那么就不能确定 array 数组的大小,报错
      1.c: In function ‘main’:
      1.c:19: error: variable-sized object may not be initialized
      1.c:19: warning: excess elements in array initializer
      1.c:19: warning: (near initialization for ‘array’)
      
    • Demo2

      //test.cpp
      #include <stdio.h>
      
      void f()
      {
          #define a 3
          const int b = 4;
      }
      
      void g()
      {
          printf("a = %d
      ", a);  //宏没有作用域
          //printf("b = %d
      ", b);  //常量由类型和作用域,编译会报错:test.cpp: In function ‘void g()’:
                                    //test.cpp:12: error: ‘b’ was not declared in this scope
      
      }
      
      int main()
      {
          const int A = 1;
          const int B = 2;
          int array[A + B] = {0};
          int i = 0;
          
          for(i=0; i<(A + B); i++)
          {
              printf("array[%d] = %d
      ", i, array[i]);
          }
          
          f();
          g();
          
          return 0;
      }
      
    • 编译无报错:AB 都是常量,编译到19行时可以从符号表中取出常量 AB 的值,可以确定数组的大小

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