提及const、static、以及#define你們都知道,我一直覺得我也是知道的,昨天一同窗說他面試時被問到#define定義一個常量和const定義一個常量有什麼不一樣,面試
我整理了下思路,發現當想向他說清楚這個問題時,我發現本身對const和#define中有些問題仍是很模糊,我想這可能就是某位高手說的:「當你能夠向別人清楚的數組
解釋某個問題時,你纔算真正懂了這個問題」。因而乎,趕忙學習了下,理理思路,記下。函數
一、c語言中:學習
1 const int i=10; 2 int array[i] ;
這個i不能說是常量而是一個不可改變的變量,它的不可改變是由編譯器肯定的,所以將 i 做爲數組的長度;會出錯,數組的長度優化
必須是一個編譯期常量(下面解釋)。在C++中這樣定義倒是能夠經過的,在C++中有一個常量摺疊概念。對象
二、編譯期常量和運行期常量內存
二者都是常量,它們的區別, 能夠用是否具有內存空間來區分
編譯期常量,
好比, #define MAX 128
這個 MAX 就是編譯期常量, 沒有對應的內存空間,
在編譯時候, 全部的 MAX 都被 128 這個值代替
運行期常量,
好比 const int x=128;
就是一個運行期常量, 分配內存空間,
可是其值不容許改變作用域
還有 const int y = ram();//ram()是一個獲取隨機數的函數,編譯器
這樣y確定是一個運行期常量,在編譯時不知道它的值,而是在運行期得到,但不可改變。編譯
三、常量摺疊
所謂「常量摺疊」是C++中編譯器的一種優化手段,對於上面的const int x = 128;編譯器通常不爲x分配內存空間,而是將它保存在一個符號表中
這樣致使的結果就是 const int x=128; 相似這樣的定義, 產生的結構和 define 同樣, 出現 x 的地方直接被 128 這個值代替了
我瞭解的,在下面狀況下const定義的常量會分配內存。
1)當用extern修飾const變量將強制爲其分配內存,由於extern表示採用外部連接,所以其必須有某個地址保存其值。
2)等取x的地址時,會強制分配內存。
3)用static 修飾時,應該也要分配內存。
四、一個類中各類變量的初始化。
//myclass.h
class myclass { public: myclass(); ~myclass(); public: int x=1;//error static int y = 2; //error const int a = 3;//error static const int b = 4;//ok }
對於上面這個類中各變量:
普通變量x若是在類定義的頭文件中初始化,因爲此時沒有定義對象,未分配內存空間,因此沒有地方存放x,或者像網友所說:要構造函數幹嗎?
靜態變量x不是屬於哪個對象的,全部對象共享,只能初始化一次,若在類中定義,那不每一個對象都初始化一次?它初始化通常爲:myclass::x = 2;
const常量在定義時就必須初始化,通常放在初始化列表中初始化。
static const定義(注:必須是整形或字符型,規定)能夠在類定義時直接初始化,首先static被全部對象共享,存儲在靜態存儲區中,其次,const限定了其不可改變,每一個對象中都同樣。
五、內部連接屬性和外部連接屬性
就是至關於c中變量或函數的做用域,static修飾的變量或函數只能在本文件中可見,const修飾的也默認爲內部連接屬性,extern修飾爲外部連接屬性(和const同時修飾時,壓過const修飾的屬性)。
可能不少說的不是很全面,歡迎指正