這有一個非常可靠的原因:C中的const并不意味著一些常量。 這只是意味著一個variables是只讀的。
在編譯器需要一個常量的地方(例如非VLA數組的數組大小),使用constvariables(如fieldWidth是不可能的。
他們不一樣
const只是一個限定符,它表示一個variables在運行時不能被改變。 但variables的所有其他function仍然存在:已經分配了存儲空間,并且可以解決此存儲空間問題。 因此,代碼不僅僅把它當作一個文字來對待,而是通過訪問指定的內存位置來引用variables(除非它是static const ,那么它可以被優化掉),并且在運行時加載它的值。 而作為一個constvariables已經分配了存儲空間,如果你把它添加到一個頭文件中,并將它包含在幾個C源代碼中,除非將其標記為extern否則將會出現“多符號定義”鏈接錯誤。 在這種情況下,編譯器無法根據實際值優化代碼(除非進行全局優化)。
#define只是用它的值replace一個名字。 此外,可以在預處理器中使用#ifdef常量:可以使用#ifdef根據其值進行條件編譯,也可以使用string化運算符#來獲取string的值。 而且由于編譯器在編譯時知道它的值,所以可以根據這個值優化代碼。
例如:
#define SCALE 1 ... scaled_x = x * SCALE;
當SCALE被定義為1 ,編譯器可以消除乘法,因為它知道x * 1 == x ,但是如果SCALE是( extern ) const ,則需要生成代碼來獲取值并執行乘法,因為值直到連接階段才會知道。 ( extern需要使用來自多個源文件的常量。)
更接近于使用#define使用枚舉:
enum dummy_enum { constant_value = 10010 };
但是這只限于整數值,并沒有#define優點,所以沒有被廣泛的使用。
當你需要從編譯它的某個庫中導入一個常量值的時候, const是很有用的,或者如果它和指針一起使用的話。 或者,如果它是通過variables索引值訪問的常量值數組。 否則, const比#define沒有任何優勢。
原因是大多數時候,你想要一個常量,而不是一個const限定的variables。 在C語言中,這兩者并不是相同的。 例如,variables作為static持續時間對象的初始值設定項的一部分無效,例如非vla數組維度(例如結構中的數組大小或任何數組前C99)。
在R的答案稍微擴展一下: fieldWidth不是一個常量expression式 ; 這是一個const限定variables。 它的值直到運行時才build立,所以在需要編譯時常量expression式的地方(比如在一個數組聲明中,或者在一個switch語句中的一個case標簽等),它不能被使用。
與預處理后擴展為常量expression式10的macrosFIELD_WIDTH比較; 這個值在編譯時是已知的,所以它可以用于數組維度,案例標簽等。
要添加到R.和Bart的答案:在C:枚舉types常量中只有一種方法來定義符號編譯時間常量。 這個標準規定這些是inttypes的。 我個人會寫你的例子
enum { fieldWidth = 10 };
但是我覺得C程序員的口味差別很大。
雖然const int并不總是合適的,但是如果你定義了一個整型值,枚舉通常會作為#define的替代。 這實際上是我在這種情況下的首選。
enum { FIELD_WIDTH = 16384 }; char buf[FIELD_WIDTH];
在C ++中,這是一個巨大的優勢,因為您可以將枚舉的范圍限定在類或名稱空間中,而不能將范圍定義為#define。
在C中,你沒有命名空間,也不能在一個結構體內枚舉枚舉的范圍,甚至不能確定你的types是否安全,所以我實際上看不到任何主要的優點,盡pipe也許有些C程序員會指出。
根據K&R(第2版,第211頁),“const和volatile屬性是ANSI標準新增的”。 這可能意味著真正舊的ANSI代碼根本就沒有這些關鍵字,這實際上只是一個傳統問題。 此外,它表示,編譯器應該檢測到更改constvariables的嘗試,但除此之外可能會忽略這些限定符。 我認為這意味著一些編譯器可能不會優化包含constvariables的代碼,以便在機器代碼中表示為中間值(就像#define一樣),這可能會花費額外的時間訪問遠端內存并影響性能。
一些C編譯器會將所有constvariables存儲在二進制文件中,如果準備大量的系數可以在embedded式世界中占用大量的空間。
相反:使用const允許在現有的程序上閃爍來改變特定的參數。
在C中定義數字常量的最好方法是使用枚舉 。 閱讀K&R的The C Programming Language,第39頁的相應章節。