程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++中Const說明

C++中Const說明

編輯:C++入門知識

最近在看程序員面試寶典,看到const這塊感覺有很大疑惑,查了很多資料,可以總結如下:

1.在C語言中

  在C語言中,const修飾的變量不具有常量的特性,只是一個不可修改的變量,實質上仍然是變量,在編譯期間無法知道它的值,不可以用作數組下標。

2.在C++中

  在C++中,const就有很大不一樣,C++中鼓勵使用const來替代#define,在C++中對const定義的變量分為兩種情況:

情況1(在.rodata段分配空間):

  如果const用在全局或者使用了static關鍵字說明,例如extern const int i=10,static const int i=10。那麼這個i就是一個常量(網上有人說真正意義上的常量),並且該常量是存放在.rodata段的,是無法通過取地址方式去修改的(具體情況見情況2),修改會報段錯誤。

情況2(不在.rodata段分配空間):

  如果const用在局部並且沒有使用static關鍵字,例如在main函數裡面const int i=10*2+1,在這種情況下,如果對該常量:1)賦值是常量表達式(沒有其它變量或者需要外界輸入的值);2)不對該常量進行一些取地址類似的操作(&),就不會對i分配空間,僅僅是將其放在符號表中;否則,就會對i分配空間,而且這個空間是在棧上的,不同於全局的是分配在.rodata段上的。另外,注意,利用編譯器反匯編的時候,可能會有一些假象,例如,在DEBUG模式下面的反匯編,編譯器生成匯編代碼為了能更好的調試,所以無論如何都會分配空間給const常量,但是如果你打開編譯器的O2優化選項的話,就不會分配空間了。

  不過,不論分不分配空間,只要該常量的賦值是常量表達式(沒有其它變量或者需要外界輸入的值),編譯器都會做一個優化,叫做常量折疊(const folding),簡單來說,就是編譯的時候,任何用到i的地方,都會直接用21去替換i。

a.有常量折疊

  如果i的賦值是常量表達式(沒有其它變量或者需要外界輸入的值),即i的值不需要訪問存儲空間來確定,那麼程序中任何出現i的地方就已經在編譯期間被替換,即使通過取地址來修改這個值,也是相當於改變了一個副本而已,如下:

const int i=1;

int *p=(int *)&i;

*p=2;

cout<<*p<<endl<<i<<endl;

輸出結果:

2

1

  這說明,i的值是確定的情況下,程序中任何出現i的地方都被1替換了。

b.無常量折疊

  另一種情況,如果賦值不是常量表達式,這時是需要訪問存儲區域才能得到確切值的,這種情況並不會有"常量折疊",如下:

int i=10;

const char gc = cin.get();   //或者const char gc = i都是一樣的

char *t = (char *)&gc;

*t += 2;

cout << *t <<endl << gc << endl;

輸如:a

輸出:

c

c

  從上面這個情況可以看出,雖然gc是局部的const,但是它的值是不確定的,是需要用戶輸入的,因此會為gc在棧中分配空間,並且因為gc的值不確定,它不能得到常量折疊帶來的優化。程序中使用gc的地方,必須直接到存儲區域去訪問才能得到值,所以*t和gc的值是保持一致的。

  無常量折疊的情況下,一定是分配了內存空間的,因為無常量折疊的本質就是值不確定,需要到內存中獲取。而有常量折疊的情況下,內存空間可能分配了,也可能沒分配,如果分配了,那是因為對該常量進行了取地址相關的操作。

volatile關鍵字:

  除此之外,volatile關鍵字也能夠屏蔽掉常量折疊,如下:

volatile const int i=1;

int *p=(int *)&i;

*p=2;

cout<<*p<<endl<<i<<endl;

輸出結果:

2

2

 

  上面是我查閱資料綜合得到的情況,具體來說,const使用情況可分為全局和局部(static關鍵字是一個因素),局部下又可分為分配內存與不分配內存、有常量折疊和無常量折疊,分不分配內存取決於是否要對該常量進行地址相關的操作(如&或者直接從內存取值),有沒有常量折疊取決於需不需要直接從內存中取值。

 

  有很多不足還請各位大神指出,大家相互學習相互進步,勿噴就好,謝謝啦

轉載請說明出處

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved