C 和 C++ 关于 const 的比较

C 语言中 const 修饰符:

  • const 修饰的变量不是真正意义上的常量,而是一个常变量

  • 无法直接修改,但是可以间接修改变量的值。会分配内存空间,因此可以通过指向其地址空间的指针去修改其内容。

    const int b = 10;
    	
    int * p = (int *)&b;
    *p = 30;
    
    printf("%x\n" , &b);		// 313b1df4
    printf("%x\n" , p);			// 313b1df4
    
    printf("%i\n" , b);			// 30,可以发现C中的常量的值这么被修改了,却没有任何报错
    printf("%i\n" , *p);		// 30
    
  • 不能把const看成一个编译期间的常量

    const int bufsize=100;
    char buf[bufsize];	// 编译错误,因为bufsize会占用内存的某个地方,因此 C 编译器不知道他在编译时候的值
    
  • C默认是外部连接的。C编译器把它作为一个生命,指明在别的地方有内存分配。

const bufsize;		// 正常编译。C是外部连接,看作一个声明



C++ 中 const 修饰符:

  • const 修饰的变量是真正的常量必须初始化

    const bufsize;		// C中正常。C++编译报错,常量必须初始化
    
  • C++默认是内部连接的。const 对象默认只能在当前文件中访问,不能再别的文件中访问(除非显式的指定extern)

  • 通常不会为其分配内存,这些常量一般以键值对的形式存放在一张符号表中,而不给其分配内存,编译过程中若发现该常量直接以符号表中的值替换。

  • 但是当使用 extern 修饰变量时(或者获取常量的地址等),则必须为变量分配空间。因为extern表示使用外部连接,说明会有其他的编译单元会使用寻址放来来引用它,因此就必须拥有自己的地址。

  • C++常量折叠:即将const常量放在符号表中,而不给其分配内存。编译器直接进行替换优化,除非用到存储空间的时候,编译器才会去分配空间,但之后获取b的值仍从符号表中读取,不过存储空间中的值如何变化

    const int b = 10;
    
    int * p = (int *)&b;
    *p = 30;
    
    printf("%x\n" , &b);		// 313b1df4
    printf("%x\n" , p);			// 313b1df4
    
    printf("%i\n" , b);			// 10,可以发现和 C 语言不同,常量的值并没有被修改
    printf("%i\n" , *p);		// 30
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章