- 高質(zhì)量程序設(shè)計指南:C++/C語言
- 林銳 韓永泉編著
- 1201字
- 2019-01-09 14:09:02
5.5 實際應(yīng)用中如何定義常量
如果要為程序中多個編譯單元或者多個模塊定義統(tǒng)一的符號常量,在C程序中你常常會把它定義在哪里呢?在C++程序中你又常常會把它定義在哪里呢?如果是只為某一個編譯單元定義符號常量,又當(dāng)如何?
表5-1是我們常用的做法。
表5-1 常用做法

(續(xù)表)

顯然,在C程序和C++程序中定義符號常量是有區(qū)別的。我們僅討論“多個編譯單元公用符號常量”的聲明和定義。
在C程序中,const符號常量定義的默認(rèn)連接類型(Linkage)是extern的,即外連接(external linkage),就像全局變量一樣。因此,如果要在頭文件中定義,必須使用static關(guān)鍵字,這樣每一個包含該頭文件的編譯單元就會分別擁有該常量的一份獨立定義實體(如同直接在每一個源文件中分別定義一次),否則會導(dǎo)致“redefinition”的編譯器診斷信息;如果在源文件中定義,除非明確改變它的連接類型為static(實際上是存儲類型為static,連接類型為內(nèi)連接)的,否則其他編譯單元就可以通過extern聲明來訪問它。
但是在C++程序中,const符號常量定義的默認(rèn)連接類型卻是static的,即內(nèi)連接(internal linkage),就像class的定義一樣,這就是在頭文件中定義而不需要static關(guān)鍵字的原因。
明白了C和C++符號常量的區(qū)別,就不難理解表5-1所列的幾種方法了。
這些做法各有優(yōu)缺點,如果是整型常量或者浮點常量,那么優(yōu)缺點都不是那么明顯。對于C++程序,我們比較一下方法二、四和方法一、三。
表5-2 方法比較

實際上,在大型應(yīng)用開發(fā)過程中,修改常量初值的事情并不會經(jīng)常發(fā)生,甚至極少會發(fā)生,即使是在維護(hù)階段,也不太可能變來變?nèi)ァR虼朔椒ǘ⑺妮^方法一、三的優(yōu)點就主要體現(xiàn)在存儲空間上了。如果是整型和浮點型常量,它們浪費的那點空間對一般應(yīng)用來說還不至于達(dá)到無法容忍的地步,不過對嵌入式應(yīng)用的開發(fā)來說也許是一件大事兒。
那什么常量最浪費空間呢?答案是字符串常量,尤其是較長的字符串常量。
字符串常量的定義和整型常量的定義差不多,但是其類型為const char *,因此我們常常這樣定義它們:
const char* const ERR_DESP_NO_MEMORY = "There is no enough memory!";
字符串常量可以在頭文件中定義并初始化,也可以在源文件中定義并初始化,但是二者差別較大:
? 如果在頭文件中定義并初始化,那么包含了該頭文件的每一個編譯單元不僅會為每一個常量指針常量(const char * const)創(chuàng)建一個獨立的拷貝項,而且也會為那個長長的字符串字面常量創(chuàng)建一個獨立的拷貝項,就相當(dāng)于在每一個編譯單元內(nèi)分別定義和初始化每一個常量一次。這是與整型或浮點型常量的定義不同的(它們在初始化完成后不再需要那個字面常量)。因此,每一個編譯單元內(nèi)訪問的字符串常量都是它自己單獨創(chuàng)建的拷貝。空間的開銷就體現(xiàn)在每一個字符串字面常量的獨立拷貝項上。
? 如果采用方法二,在頭文件中聲明所有常量指針常量,而在源文件中定義并初始化它們,則每一個包含該頭文件的編譯單元訪問的不僅是常量指針常量的唯一實體,而且字符串字面常量也是唯一的實體。這就大大節(jié)約了內(nèi)存,而且不影響效率。
當(dāng)然,我們完全可以把常量合并的優(yōu)化交給編譯器和連接器來完成,但是我們還是提倡由自己來優(yōu)化常量的定義。
- scikit-learn Cookbook
- The Complete Rust Programming Reference Guide
- JavaScript前端開發(fā)模塊化教程
- Deploying Node.js
- PHP程序設(shè)計(慕課版)
- Offer來了:Java面試核心知識點精講(原理篇)
- 3D少兒游戲編程(原書第2版)
- Visual C#.NET程序設(shè)計
- Hands-On Reinforcement Learning with Python
- SQL Server與JSP動態(tài)網(wǎng)站開發(fā)
- Learning Apache Cassandra
- Java網(wǎng)絡(luò)編程實戰(zhàn)
- Java程序員面試筆試寶典(第2版)
- 編程改變生活:用Python提升你的能力(進(jìn)階篇·微課視頻版)
- 零基礎(chǔ)學(xué)C++(升級版)