第3课 - 进化后的const分析

Posted Hengs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第3课 - 进化后的const分析相关的知识,希望对你有一定的参考价值。

第3课 - 进化后的const分析

1. C 语言中的 const

  (1)const 修饰的变量具有只读属性,本质还是变量,只是告诉编译器该变量不能出现在赋值符号的左边

  (2)const 修饰的局部变量在栈上分配空间,修饰的全局变量在只读存储区分配空间

  (3)const 只在编译期间有用,在运行期间无用。const 不能定义真正意义上的常量(const英文含义)!

  (4)C 语言中的常量只有枚举这一种类型。

 1 #include <stdio.h>
 2 
 3 int main(void)
 4 {
 5     const int i = 10;
 6     
 7     int *p = (int *)(&i);    // 取得 i 变量的地址
 8     
 9     *p = 1;
10     
11     printf("i = %d\\n", i);    // i = 1
12 
13 
14     return 0;
15 }
const修饰局部变量
 1 #include <stdio.h>
 2 
 3 const int i = 10;
 4 
 5 int main(void)
 6 {
 7     int *p = (int *)(&i);    
 8     
 9     *p = 1;    // 发生段错误
10     
11     printf("i = %d\\n", i);    
12 
13     return 0;
14 }
15 
16 /***
17     程序会发生段错误,const修饰的全局变量放在只读存储区,不能通过指针进行修改
18 ***/
const修饰的全局变量

2. C++ 中的 const

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

  (1)当编译器碰见 const 声明时在符号表中放入常量

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

      何为符号表?符号表是编译器在编译程序时产生的一张表格,其本质是编译器在编译程序时产生的一种数据结构

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

      ① 对 const 常量使用了 extern 关键字

      ② 对 const 常量使用 & 操作符

  Note1:C++ 编译器虽然可能为 const 常量分配内存空间,但不会使用其存储空间中的值,这样做只是为了兼容 C 语言。

  Note2何为兼容? C++ 完全兼容 C 指的是,用C编译器能编译通过的 C 程序,使用 C++ 编译器也可以成功编译,但是执行结果不一定相同

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     const int c = 0;      //C语言中会为变量c分配内存
 6     int* p = (int *)&c;   //C++中遇到&才为c分配内存
 7     
 8     printf("Begin...\\n");
 9     
10     *p = 5;
11     
12     printf("c = %d\\n", c);   // C语言会输出内存中的5
13                                         // C++中会从符号表(而不是内存)中取值,所以为0
14 
15     printf("*p = %d\\n", *p);
16     
17     printf("End...\\n");
18     
19     return 0;
20 }
21 
22 //  在C中的输出结果: c = 5 , *p = 5
23 //  在C++中的输出结果:c = 0 , *p = 5
C/C++中的const

3. 对比 C/C++ 中的 const

  本质 分配内存
C 只读变量

局部变量分配在栈上;全局变量分配在只读存储区

C++ 常量

当使用 & 操作符对 const 常量取地址时会分配内存空间;

当 const 修饰全局变量,并且在其它文件中使用 extern 引用时会分配内存空间

4. C++ 中的 const 与宏的区别

  定义 处理方式
C++ 中的 const const int c = 5; 由编译器处理,编译器会进行类型检查和作用域检查
# define c 5 由预处理器处理,只是简单的文本替换
 1 #include <stdio.h>
 2 
 3 void f()
 4 {
 5     #define a 3            // 宏没有作用域的概念
 6     const int b = 4;    // const有作用域的概念,只在f()内部有效,g()不能引用
 7 }
 8 
 9 void g()
10 {
11     printf("a = %d\\n", a);
12     printf("b = %d\\n", b);    // 这里会发生错误
13 }
14 
15 int main()
16 {
17     const int A = 1;
18     const int B = 2;
19     int array[A + B] = {0};  // 在C中编译该句代码时,由于 A+B 两个变量的和只能在运行时确定,因此会报错
20                              // C++可以从符号表中取得A + B的值为3
21     int i = 0;
22     
23     for(i=0; i<(A + B); i++)
24     {
25         printf("array[%d] = %d\\n", i, array[i]);
26     }
27     
28     f();
29     g();
30     
31     return 0;
32 }
C++中的const与宏

5. 小结

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

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

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

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

 

注:本文总结于狄泰唐老师的《C++深度解析》课程

狄泰QQ群:199546072

本人QQ号:502218614

以上是关于第3课 - 进化后的const分析的主要内容,如果未能解决你的问题,请参考以下文章

进化后的 const

第9课 const和volatile分析

第5课.引用的本质分析

第5课 引用的本质分析

第13课 类族结构的进化

病毒进化树构建