zoukankan      html  css  js  c++  java
  • 进化后的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常量的语法特性




  • 相关阅读:
    WHERE col1=val1 AND col2=val2;index exists on col1 and col2, the appropriate rows can be fetched directly
    MySQL 交集 实现方法
    MBProgressHUD的使用
    Xcode4 使用 Organizer 分析 Crash logs(转)
    SimpleXML 使用详细例子
    PHP的XML Parser(转)
    iPhone,iPhone4,iPad程序启动画面的总结 (转)
    Pop3得到的Email 信件格式介绍
    yii总结
    隐藏Tabbar的一些方法
  • 原文地址:https://www.cnblogs.com/-glb/p/11240578.html
Copyright © 2011-2022 走看看