• 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 的值,可以确定数组的大小

  • 相关阅读:
    Spring源码解读 推荐流程
    Spring源码解读 推荐流程
    验证数据归属
    验证数据归属
    maven用途、核心概念、用法、常用参数和命令、扩展
    Reverse Linked List II
    Insertion Sort List
    Palindrome Partitioning
    Construct Binary Tree from Preorder and Inorder Traversal
    Valid Parentheses
  • 原文地址:https://www.cnblogs.com/bky-hbq/p/13695152.html
Copyright © 2020-2023  润新知