數值巨集常量#define 巨集定義可以定義在**的任何地方,從本行巨集定義開始到後面**都認識這個巨集;可以把任何東西定義成巨集。因為編譯器在預編譯的時候用真身替換替身,然而在**裡面卻又常用替身來幫忙。巨集定義是個演技高超的替身演員,但也會經常耍大牌的,我們慎用它。
#define pi 3.141592654
在**中你盡可以使用pi來代替3.141592654,若你要把pi精度再提高一些,你需要乙個乙個的去修改這串數,你能保證不漏不出錯?若使用pi的巨集定義的話,我們只需要修改一次(十分高效)。
這種情況還不是最糟糕的,下面再看乙個例子:
#define error_poweroff -1
如果你在**裡不用error_poweroff這個巨集而用-1,尤其在函式返回錯誤**的時候(往往乙個開發乙個系統需要定義很多錯誤**)。肯怕上帝都無法知道-1表示的是什麼意思吧。這個-1,我們一般稱為「魔鬼數」,上帝遇到它也會發狂的。所以,從**可讀性的角度進行考慮,**裡一定不要出現「魔鬼數」。
但是我們利用define來定義數值型別的資料,一般只是用來定義常量 ,如果要定義一些變數,則可以使用c語言中const關鍵字。const 修飾的資料是有型別的,而define 巨集定義的資料沒有型別。為了安全,我建議你在定義一些巨集常數時用const代替,編譯器會給const 修飾的唯讀變數做型別校驗,減少錯誤的可能。
const修飾的不是常量而是readonly的變數,const 修飾的唯讀變數不能用來定義陣列的維數,也不能放在case關鍵字後面。
字串巨集常量除了定義巨集常數之外,經常還用來定義字串,尤其是路徑:
a) #define eng_path_1 e:\glish\lisen_to_tis\listen_to_this_3
b) #define eng_path_2 「e:\glish\liten_to_tis\listen_to_this_3」
到底哪乙個正確呢?如果路徑太長,一行寫下來比較彆扭,用反斜槓接續符 '\' :
c) #define eng_path_3 e:\glish\lisen_to_tis\listen\_to_this_3
這裡用了4 個反斜槓,哪個是接續符?反斜槓作為接續符時,在本行其後面不能再有任何字元,空格都不行。所以,只有最後乙個反斜槓才是接續符。至於a)和b),那要看你怎麼用了,既然define 巨集只是簡單的替換,那給eng_path_1 加上雙引號不就成了:「eng_path_1」。
注意:有的系統裡規定路徑的要用雙反斜槓「\\」,比如(這是正確的版本):
#define eng_path_4 e:\\glish\\lisen_to_tis\\listen_to_this_3
注釋符號#define bs //
#define bm /*
#define em */
1) bs my single-line comment
2) bm my multi-line comment em
1)、2)都是錯誤的,因為注釋先於預處理指令被處理,當這兩行被展開成//…或/*…*/時,注釋已處理完畢,此時再出現//…或/*…*/自然錯誤。因此,試圖用巨集開始或結束一段注釋不可行。
巨集定義表示式定義一年有多少秒:
#define second_one_year 60*60*24*365
在16位系統下把這個數賦給整型變數的時候可能會溢位?一年有多少秒不可能是負數。修改一下:
#define second_one_year (60*60*24*365)ul
這裡的括號是否有必要?接著看,定義乙個巨集函式,求x 的平方:
#define sor (x) x * x
試試:假設x 的值為100,sor (x)被替換後變成100*100,沒有問題。
再試試:假設x 的值是個表示式100+1,sor (x)被替換後變成100+1*100+1。問題來了,這並不是我想要得到的。怎麼辦?括號括起來不就完了?
#define sor (x) ((x)*(x))
最好在最外層也加上括號,看例子,求兩個數的和:
#define add (x) (x)+(x)
如果x 是個表示式50*3,**又寫成這樣:add(x)* add(x)。替換後:(50*3)+(50*3)*(50*3)+(50*3)。出錯,所以最外層的括號最好別省。define 是個演技高超的替身演員,但也經常耍大牌。要搞定它其實很簡單,加上括號。
注意這一點:巨集函式被呼叫時是以實參代換形參。而不是「值傳送」。
巨集定義中的空格#define sum (x) (x)+(x)
這還是定義的巨集函式sum(x)嗎?顯然不是。編譯器認為這是定義了乙個巨集:sum,代表的是(x) (x)+(x)。
為什麼會這樣呢?問題還在於sum 後面的這個空格。所以在定義巨集的時候一定要注意什麼時候該用空格,什麼時候不該用空格。這個空格僅僅在定義的時候有效,在使用這個巨集函式的時候,空格會被編譯器忽略掉。也就是說,上一節定義好的巨集函式sum(x)在使用的時候在sum 和(x)之間留有空格是沒問題的。比如:sum(3)和sum (3)的意思是一樣的。
#undef#undef 是用來撤銷巨集定義的,用法如下:
#define pi 3.141592654
...... // code
#undef pi
//下面的**就不能用pi 了,它已經被撤銷了巨集定義。
寫好c語言,漂亮的巨集定義很重要,使用巨集定義可以防止出錯,提高可移植性,可讀性,方便性 等等。下面列舉一些成熟軟體中常用得巨集定義:
1,防止乙個標頭檔案被重複包含
#ifndef comdef_h
#define comdef_h
//標頭檔案內容
#endif
得到指定位址上的乙個位元組或字
#define mem_b( x ) (*((byte*) (x)))
#define mem_w( x ) (*( (word*) (x)))
求最大值和最小值
#define max(x, y) (((x) > (y)) ? (x) : (y))
#define min(x, y) (((x) < (y)) ? (x) : (y))
返回陣列元素的個數
#define arr_size(a) (sizeof((a)) / sizeof( (a[0])))
ansi標準說明了五個預定義的巨集名。它們是:
_ line _
_ file _
_ date _
_ time _
_ stdc _
當定義了_debug,輸出資料資訊和所在檔案所在行
#ifdef _debug
#define debugmsg(msg,date) printf(msg); printf(「%d%d%d」, date, _line_, _file_)
#else
#define debugmsg(msg,date)
#endif
C 巨集定義 define
可以用 define命令將乙個指定的識別符號 即巨集名 來代表乙個字串。定義巨集的作用一般是用乙個短的名字代表乙個長的字串。它的一般形式為 define 識別符號 字串 這就是已經介紹過的定義符號常量。如 define pi 3.1415926 還可以用 define命令定義帶引數的巨集定義。其定義...
C語言 define拼接巨集定義實現
使用場合 拼接兩個巨集,乙個是傳入的巨集。但是傳入的巨集不會被替換,反而原封不動的接了上去,這就尷尬了。經過各種嘗試,居然成了,特此記錄分享一下,方便大家學習。char a param 0 char b param 0 新增巨集定義 define define x x param 一次定義 defi...
C語言 巨集定義 define的用法
這種用法是最簡單最常見的一種方式,如下 define pai 3.14注意 它的功能是在程式中若出現了pai,就把它替換為3.14,示例程式如下 include define pai 3.14 不帶參巨集定義 intmain 使用方法如下 define add a,b a b 它的功能是計算a b的...