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