歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C語言宏定義#define

C語言宏定義#define

日期:2017/3/1 9:56:31   编辑:Linux編程

一、數值宏常量

#define 宏定義是個演技非常高超的替身演員,但也會經常耍大牌的,所以我們用它要慎之又慎。它可以出現在代碼的任何地方,從本行宏定義開始,以後的代碼就就都認識這個宏了;也可以把任何東西定義成宏。因為編譯器會在預編譯的時候用真身替換替身,而在我們的代碼裡面卻又用常常用替身來幫忙。看例子:

#define PI 3.141592654
在此後的代碼中你盡可以使用PI 來代替3.141592654,而且你最好就這麼做。不然的話,如果我要把PI 的精度再提高一些,你是否願意一個一個的去修改這串數呢?你能保證不漏不出錯?而使用PI 的話,我們卻只需要修改一次。這種情況還不是最要命的,我們再看一個例子:
#define ERROR_POWEROFF -1

如果你在代碼裡不用ERROR_POWEROFF 這個宏而用-1,尤其在函數返回錯誤代碼的時候(往往一個開發一個系統需要定義很多錯誤代碼)。肯怕上帝都無法知道-1 表示的是什麼意思吧。這個-1,我們一般稱為“魔鬼數”,上帝遇到它也會發狂的。所以,我奉勸你代碼裡一定不要出現“魔鬼數”。

我們已經討論了const 這個關鍵字,我們知道const 修飾的數據是有類型的,而define 宏定義的數據沒有類型。為了安全,我建議你以後在定義一些宏常數的時候用const代替,編譯器會給const 修飾的只讀變量做類型校驗,減少錯誤的可能。但一定要注意const修飾的不是常量而是readonly 的變量,const 修飾的只讀變量不能用來作為定義數組的維數,也不能放在case 關鍵字後面。

二、字符串宏常量

除了定義宏常數之外,經常還用來定義字符串,尤其是路徑:
A),#define ENG_PATH_1 E:\English\listen_to_this\listen_to_this_3
B),#define ENG_PATH_2 “E:\English\listen_to_this\listen_to_this_3”
噢,到底哪一個正確呢?如果路徑太長,一行寫下來比較別扭怎麼辦?用反斜槓接續符啊:
C), #define ENG_PATH_3 E:\English\listen_to_this\listen\_to_this_3
還沒發現問題?這裡用了4 個反斜槓,到底哪個是接續符?回去看看接續符反斜槓。

反斜槓作為接續符時,在本行其後面不能再有任何字符,空格都不行。所以,只有最後一個反斜槓才是接續符。至於A)和B),那要看你怎麼用了,既然define 宏只是簡單的替換,那給ENG_PATH_1 加上雙引號不就成了:“ENG_PATH_1”。

但是請注意:有的系統裡規定路徑的要用雙反斜槓“\\”,比如:

#define ENG_PATH_4 E:\\English\\listen_to_this\\listen_to_this_3

三、用define 宏定義注釋符號

上面對define 的使用都很簡單,再看看下面的例子:
#define BSC //
#define BMC /*
#define EMC */
D),BSC my single-line comment
E),BMC my multi-line comment EMC

D)和E)都錯誤,為什麼呢?因為注釋先於預處理指令被處理,當這兩行被展開成//…或/*…*/時,注釋已處理完畢,此時再出現//…或/*…*/自然錯誤.因此,試圖用宏開始或結束一段注釋是不行的。

四、用define 宏定義表達式

這些都好理解,下面來點有“技術含量”的,定義一年有多少秒:
#define SEC_A_YEAR 60*60*24*365
這個定義沒錯吧?很遺憾,很有可能錯了,至少不可靠。你有沒有考慮在16 位系統下把這樣一個數賦給整型變量的時候可能會發生溢出?一年有多少秒也不可能是負數吧。修改一下:
#define SEC_A_YEAR (60*60*24*365)UL
又出現一個問題,這裡的括號到底需不需要呢?繼續看一個例子,定義一個宏函數,求x 的平方:
#define SQR (x) x * x

對不對?試試:假設x 的值為10,SQR (x)被替換後變成10*10。沒有問題。

再試試:假設x 的值是個表達式10+1,SQR (x)被替換後變成10+1*10+1。問題來了,這並不是我想要得到的。怎麼辦?括號括起來不就完了?

#define SQR (x) ((x)*(x))
最外層的括號最好也別省了,看例子,求兩個數的和:
#define SUM (x) (x)+(x)
如果x 的值是個表達式5*3,而代碼又寫成這樣:SUM (x)* SUM (x)。替換後變成:(5*3)+(5*3)*(5*3)+(5*3)。又錯了!所以最外層的括號最好也別省了。我說過define 是個演技高超的替身演員,但也經常耍大牌。要搞定它其實很簡單,別吝啬括號就行了。

注意這一點:宏函數被調用時是以實參代換形參。而不是“值傳送”。

Copyright © Linux教程網 All Rights Reserved