• 进化后的const分析


    C语言中的const

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

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

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

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

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

    总结:

    C语言中的const使得变量具有只读属性

    const将具有全局生命周期的变量存储于只读存储区

    const不能定义真正意义上的常量!

    C语言中只有通过enum定义的标识符才是真正意义上的常量。

    编程实验

    C/C++中的const

    假设为test.c

     1 #include <stdio.h>
     2 
     3 int main()
     4 
     5 {
     6 
     7   const int c = 0;
     8 
     9   int *p = (int*)&c;
    10 
    11   printf("Begin...
    ");
    12 
    13   *p = 5;
    14 
    15   printf("c = %d
    ",c);      
    16 
    17   printf("End ...
    ");
    18 
    19   return 0;
    20 
    21 }

     1)利用C编译器,即执行

    gcc test.c 

    ./a.out 

    得到C的值为5;

    2)利用C++编译器,即执行

    g++ test.c

    ./a.out

    得到C的值是0,

    说明第13行*p = 5 不起作用了。

    同一个程序用C语言编译器和用C++编译器编译得到的运行结果不同。

    下面再来修改程序,观察程序的运行结果:

     1 #include <stdio.h>
     2 
     3 int main()
     4 
     5 {
     6 
     7   const int c = 0;
     8 
     9   int *p = (int*)&c;
    10 
    11   printf("Begin...
    ");
    12 
    13   *p = 5;
    14 
    15   printf("c = %d
    ",c);      
    16    printf("*p = %d
    ",*p);
    17   printf("End ...
    "); 

      return 0;

    }

    利用C编译器,得到

    c = 5;

    *p = 5;

    利用C++编译器,得到

    c = 0;

    *p = 5;

    为什么会这样呢?

    说明了const关键字在从C语言到C++语言的进化中得到了很大的改变。那么变化究竟在哪里呢?

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

    ——当碰见const声明时在符号表中放入常量

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

    ——编译过程中若发现下述情况则给对应的常量分配存储空间(C++天生兼容C语言,也会有给常量分配空间的情况)

      对const常量使用了extern

      对const常量使用了&操作符

    注意:

    C++编译器虽然可能为const常量分配空间,但不会使用其存储空间中的值。(就是为了兼容C语言,兼容的意义就在于以前用C编译器编译过得程序,也能用C++编译器编译过,但运行的结果可能不同)

    C语言中的const变量

    ——C语言中const变量是只读变量,会分配存储空间

    C++中的const常量(从C语言中的只读变量变为一个常量了,但为了兼容C语言,可能为常量分配空间)

    ——可能分配存储空间

      当const常量为全局,并且需要在其他文件中使用

      当使用&操作符对const常量取地址

    C++中的const常量类似于宏定义

    ——const int c = 5; 约等于 #define c 5

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

    ——const常量是由编译器处理

    ——编译器对const常量进行类型检查和作用域检查

    ——宏定义由预处理器处理,单纯的文本替换

    const与宏的代码分析

     1 #include <stdio.h>
     2 
     3 void f()
     4 {
     5     #define a 3
     6     const int b = 4;
     7 }
     8 
     9 void g()
    10 {
    11     printf("a = %d
    ", a);
    12     //printf("b = %d
    ", b);
    13 }
    14 
    15 int main()
    16 {
    17     const int A = 1;
    18     const int B = 2;
    19     int array[A + B] = {0};
    20     int i = 0;
    21     
    22     for(i=0; i<(A + B); i++)
    23     {
    24         printf("array[%d] = %d
    ", i, array[i]);
    25     }
    26     
    27     f();
    28     g();
    29     
    30     return 0;
    31 }

    1)用C语言编译器进行编译,会发现出错。出错的地方在于:

    int array[A + B] = {0};
    虽然A与B是由const修饰的,根据上面所学的知识,A和B都是只读变量。数组的长度用两个变量相加,相加的结果到运行的时候才知道,
    编译器就不乐意了,因此肯定会出错。

    2)用C++编译器进行编译,就通过了。

    此时A和B就是真正意义上的常量了。因此A+B也是常量

    注意一个地方:

    在g()函数中直接访问f()函数所定义的宏变量,结果没有出错,为什么?

    因为宏是被预处理所处理的,直接进行文本替换,编译器压根不知道宏是什么,根本不知道宏的存在。其实,编译器看到的是这样的代码:

    printf("a = %d
    ",3);

    说明宏是没有作用域的概念的。

    在g()函数中调用

     printf("b = %d ", b);是不对的。

    小结:

    与C语言不同,C++中的const不是只读变量

    C++中的const是一个真正意义上的常量

    C++编译器可能会为const常量分配空间

    C++完全兼容C语言中const常量的语法特性




  • 相关阅读:
    Linux从程序到进程
    Linux用户与“最小权限”原则
    Linux进程关系
    Linux信号基础
    Linux进程基础
    Sublime Text 报“Pylinter could not automatically determined the path to lint.py
    Linux文本流
    Linux文件管理相关命令
    Linux命令行与命令
    Linux架构
  • 原文地址:https://www.cnblogs.com/-glb/p/11240578.html
Copyright © 2020-2023  润新知