我們知道c程式在編譯過程之前,c語言預處理器首先對程式**作了了必要的轉換處理。 巨集在c程式中是非常有用的,比如我們可以通過修改巨集定義來修改在程式中出現的所有例項。同時通過巨集定義還可以免去函式呼叫帶來的重大系統開銷。
雖然巨集定義非常有用,但是巨集定義也是非常容易出錯的。主要表現為以下幾點:
1、 不能忽視巨集定義中 的空格
比如在下面的巨集定義中
#define f (x) ((x)-1) 因為在f和(x)之間有乙個空格,所以這個巨集定義實際代表的是f 代表(x) ((x)-1),這和我們預想的f (x)代表((x)-1)相去甚遠。
****這裡需要特別注意的是,雖然在巨集定義的時候空格不能忽視,但是當我們在程式中用到巨集定義時,空格卻是可以忽略的,比如我們的巨集定義中#define f(x) x+3;在程式中我們可以用f(x)來呼叫該巨集,這時候是沒有任何錯誤的。
2、巨集並不是函式
因為巨集從表面上看其行為與函式非常相似,我們有時候會把他們視為完全相同。然而情況卻並非如此。
比如我們定義乙個巨集 #define max(a,b) a>b?a:b; 但是當我們計算max(x-z,y-z)時,巨集展開後的結果卻和我們預想的相去甚遠,展開為 x-z>y-z?x-z:y-z; 顯然這不是我們想要的結果。因此在進行巨集定義的時候我們最好都把每個引數用大括號括起來。同樣整個結果表示式也應該用括號括起來,以防止當巨集用於乙個更大一些的表示式中可能出現的錯誤問題。
是不是這樣的巨集就沒有任何問題了,當然不是!!!!!!!!!!!在巨集呼叫中,如果乙個運算元在兩處被呼叫,就會被求值兩次,比如我們定義的巨集#define max(a,b) a>b?a:b; 在進行巨集呼叫時,max(x++,y++);中的x和y都用可能被++兩次,解決這種問題的方法有兩個,要麼不使用巨集呼叫,將巨集改為函式,要麼巨集呼叫中的引數沒有***。
3、巨集並不是型別定義
很多程式設計者都喜歡用巨集來定義一種資料型別,比如 :
#define footype struct foo *
footype a;
footype b,c;
程式設計者本來的意圖是將b,c都定義為指向結構的指標,而事實上將第二個宣告擴充套件開為
struct foo * a,b;
這個語句中a被定義為乙個指向結構的指標,而b卻被定義為乙個結構(而不是指標);
預處理器之巨集定義
以 開頭的命令都是預處理命令,預處理不是c語言的語句,不能被編譯器編譯。所以在編譯之前需要使用預處理器做檔案的預處理工作。在編譯之前,所有的預處理語句都要被處理 替換或展開 eg1 一般巨集定義 define num 100eg2 有引數的巨集定義 define s a,b a beg3 寫乙個巨集...
預處理器(巨集的用法)
編譯器在對巨集預處理時,會 1.將標頭檔案展開 2.去掉注釋 3.巨集替換 4.條件編譯 巨集替換時應注意的幾點 1 會把它兩邊的字元轉換為乙個字元 2 巨集要替換乙個函式或者引數時,需要加上 3 鄰近字元連線原則 4 value value指代乙個變數名,會將該字面值轉換為乙個字串 value 1...
xcodebuild 如何定義預處理器巨集
您在xcodebuild命令列上傳遞gcc preprocessor definitions。請記住,對於類似shell的單詞拆分和引用處理,將重新評估引數,因此您需要小心,尤其是當您的巨集值不僅僅是簡單的1時 例如,nsstring文字 同樣重要的是在你設定的值內擴充套件gcc preproces...