const在C和C 中的區別

2021-10-23 09:10:17 字數 2274 閱讀 6438

在c中,const不是常量,只能說是乙個不能改變變數(注意是變數),c編譯器不能把const看成乙個編譯期間的常量,因為他在記憶體中有分配,c編譯器不知道他在編譯期間的值。所以不能作為陣列定義時的下標,因為它必須為常量。

在c中,const int a;是可以的,因為這只是宣告乙個變數,告訴編譯器,我這裡是宣告,指明在別的地方有記憶體分配。但在c++中這樣寫是不正確的,c++中const預設是內部鏈結,c中預設是外部鏈結,為了起到和c語言一樣的效果,c++需要將const修飾為extern,因為extern優先順序高於const,所以變數會被變為extern外部鏈結,起到和c語言一樣的效果。

通俗的講:在c++ 中const 物件預設為檔案的區域性變數。與其他變數不同,除非特別說明,在全域性作用域宣告的 const 變數是定義該物件的檔案的區域性變數。此變數只存在於那個檔案中,不能被其他檔案訪問。通過指定 const 變更為 extern,就可以在整個程式中訪問 const 物件。

c++中是否為const分配記憶體空間要看具體情況,如果被宣告為extern或者取const變數位址,就需要為const變數分配空間。

當在自己的檔案中使用const的時候,c++不會為const常量分配空間,因為這是一種優化措施,沒有必要浪費空間去儲存乙個常量,此時const int a=5 就相當於#define a 5,當在其他檔案使用的時,需要分配記憶體,同樣在程式內部引用的時候,也需要分配記憶體,因為這兩者都是採用定址的技術去使用的,不分配記憶體就沒有位址。c++中定義常量的時候不再採用define,因為define只做簡單的巨集替換,並不提供型別檢查。

c++中用const定義了乙個常量後,不會分配乙個空間給它,而是將其寫入符號表(symbol table),這使得它成為乙個編譯期間的常量,沒有了儲存與讀記憶體的操作,使得它的效率也很高。但是const定義的常量本質上也是乙個變數,是變數就會有位址,那麼什麼時候會分配記憶體?

int

main()

/*執行結果:

-----------

010ff958

010ff958230

-----------

*/

通過 intp = (int)(&a);這種方法,可以直接修改const常量對應的記憶體空間中的值,但修改不會影響到常量本身的值,因為用到a的時候,編譯器根本不會去進行記憶體空間的讀取。這就是c++的常量摺疊constant folding,即將const常量放在符號表中,而並不給其分配記憶體。編譯器直接進行替換優化。除非需要用到a的儲存空間的時候,編譯器迫不得已才會分配乙個空間給a,但之後a的值仍舊從符號表中讀取,不管a的儲存空間中的值如何變化,都不會對常量a產生影響。

但是在c語言中卻不是這樣,c沒有constant folding的概念,用const定義乙個常量的時候,編譯器會直接開闢乙個記憶體空間存放該常量。不會進行優化。同樣的例子在c下面會產生不同的結果:

int

main()

/*執行結果

------------

61fe14

61fe14

3030

------------*/

c中,乙個被const定義為常量的值,卻能被修改,而且編譯器不報任何錯誤 。進一步深入可發現,對於以上兩個例子來說,a都是定義在某個函式之內的(比如main()函式),不管是c還是c++,本質上都只是將其當成乙個普通的區域性變數來對待,都只是在棧上分配空間。所以const根本就不能起到阻止修改其記憶體空間的作用,乙個合法的強制型別轉換就可以輕鬆搞定。c++比c好的地方就在於使用了constant folding的機制,使得常量的值跟對應的記憶體空間無關,從而保護了該常量值。

以上的例子針對區域性的const常量而言,對全域性的const變數,c++仍舊採用constant folding策略,故以下**是行得通的:

const

int a =3;

int arr[a]

;

但c會報錯: error: variably modified 『arr』 at file scope, 原因在於gcc認為a只是乙個普通的全域性變數,而變數是不能用來指定陣列的長度的,這是針對全域性陣列而言。但如果是區域性的陣列的話,就算是int a = 3; int arr[a];這種都是可以的,若在c和c++中如果我們仍然用int p = (int)(&a);這種方法來修改它記憶體中的值,編譯時不會報錯,但是執行時會報錯誤,因為a是放在唯讀的全域性資料區中,修改該區中的資料會引發段錯誤。

const 在c和c 中的區別

c 中的const正常情況下是看成編譯期的常量,編譯器並不為const分配空間,只是在編譯的時候將期值儲存在名字表中,並在適當的時候折合在 中.所以,以下 include using namespace std int main for int i 0 i sizeof array sizeof a...

const在C和C 中的區別

1,怎麼理解const?2,const在c和c 中的區別?const修飾的變數不能夠在作為左值,也就是說一旦被初始化後,值不可以被修改。在.c檔案中,const修飾的量,可以不用初始化,但是如果不初始化,那也就沒有機會給被修飾量進行賦值。c語言中const修飾的量不叫常量,而叫做常變數,和普通變數的...

const在C與C 中的區別

const修飾的變數稱為常變數,在編譯階段,判斷其有沒有做左值,其他用法與普通變數一樣。普通變數存放資料在執行階段才能知道 const修飾的變數稱為常量,也是在編譯階段,將常量出現的地方替換為相應初始化的值 1.常量不能修改 直接與間接 2.const 修飾全域性變數是將其變為local 3.必須初...