文章轉自: http://www.cnblogs.com/good90/archive/2012/03/19/2405757.html
說起const、static、以及#define大家都知道,我一直以爲我也是知道的,昨天一同學說他面試時被問到#define定義一個常量和const定義一個常量有什麼不同,
我整理了下思路,發現當想向他說清楚這個問題時,我發現自己對const和#define中有些問題還是很模糊,我想這可能就是某位高手說的:“當你可以向別人清楚的
解釋某個問題時,你纔算真正懂了這個問題”。於是乎,趕緊學習了下,理理思路,記下。
1、c語言中:
1 const int i=10;
2 int array[i] ;
這個i不能說是常量而是一個不可改變的變量,它的不可改變是由編譯器確定的,因此將 i 作爲數組的長度;會出錯,數組的長度
必須是一個編譯期常量(下面解釋)。在C++中這樣定義卻是可以通過的,在C++中有一個常量摺疊概念。
2、編譯期常量和運行期常量
兩者都是常量,它們的區別, 可以用是否具備內存空間來區分
編譯期常量,
比如, #define MAX 128
這個 MAX 就是編譯期常量, 沒有對應的內存空間,
在編譯時候, 所有的 MAX 都被 128 這個值代替
運行期常量,
比如 const int x=128;
就是一個運行期常量, 分配內存空間,
但是其值不允許改變
還有 const int y = ram();//ram()是一個獲取隨機數的函數,
這樣y肯定是一個運行期常量,在編譯時不知道它的值,而是在運行期獲得,但不可改變。
3、常量摺疊
所謂“常量摺疊”是C++中編譯器的一種優化手段,對於上面的const int x = 128;編譯器一般不爲x分配內存空間,而是將它保存在一個符號表中
這樣導致的結果就是 const int x=128; 類似這樣的定義, 產生的結構和 define 一樣, 出現 x 的地方直接被 128 這個值代替了
我瞭解的,在下面情況下const定義的常量會分配內存。
1)當用extern修飾const變量將強制爲其分配內存,因爲extern表示採用外部鏈接,因此其必須有某個地址保存其值。
2)等取x的地址時,會強制分配內存。
3)用static 修飾時,應該也要分配內存。
4、一個類中各種變量的初始化。
//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限定了其不可改變,每個對象中都一樣。
5、內部鏈接屬性和外部鏈接屬性
就是相當於c中變量或函數的作用域,static修飾的變量或函數只能在本文件中可見,const修飾的也默認爲內部鏈接屬性,extern修飾爲外部鏈接屬性(和const同時修飾時,壓過const修飾的屬性)。