2013-03-22 54 views
4

我想了解像宏一樣的函數的想法,但是有幾點讓我很困惑。例如說我們有:像宏中的函數C

#define Max(a,b) ((a)>(b)) ? (a):(b)) 

,我把它像這樣

int i = Max(4,5); 

這將評估條件表達式相當於a>b?如果是,那麼a,否則b。但我很困惑,Max函數如何知道如何處理這些參數。與實際功能不同,該實現不是用調用程序中的代碼編寫的。定義陳述的權利是否對我這樣做?它對我來說只是一件新事物,我想確保我理解這裏發生的事情。

像宏一樣的函數的這個特殊部分讓我困惑。我知道這些類型的宏對於降低開銷成本很有用,因爲它們排除了在堆棧上節省內存的JSR RTS處理器指令。

+1

這不是一個功能。宏實際上只是文本替換,在編譯器運行之前發生。 – 2013-03-22 16:37:22

+0

[This](http://gcc.gnu.org/onlinedocs/cpp/Macro-Arguments.html)可能會有所幫助。 – ajp15243 2013-03-22 16:38:46

+0

您是否意識到'?'是一個三元條件操作符? – 2013-03-22 16:39:30

回答

9
#define Max(a,b) ((a)>(b)) ? (a):(b)) 

是一個宏觀的,導致沒有別的,但你的代碼中一個簡單的文本替換,這意味着預處理此行期間:

int i = Max(4,5); 

改爲:

int i = ((4)>(5)) ? (4):(5)); 

請注意,在使用像這樣的宏時沒有類型安全性,並且在調試代碼時也很難。拇指良好的規則是:不要使用宏時,你可以達到同樣的使用功能

int max(int a, int b) { 
    return (a > b) ? a : b; 
} 
+0

啊所以通過輸入安全性,你的意思是我理論上可以傳遞一個int,char等,它仍然是有效的? – PresidentRFresh 2013-03-22 16:47:46

+2

我實際上認爲這個涉及'max()'的特殊例子是使用宏而不是函數的好時機。在C中,沒有模板或泛型,你必須爲每種類型編寫一個單獨的'max()'函數,而對於一個簡單的宏,它只是工作(對於'>'有意義的類型)。 – 2013-03-22 16:50:30

+0

@PresidentRFresh:任何東西都可以「傳遞」給這個宏。問題是,有時它可能會導致錯誤的行爲(宏以一種他們不打算使用的方式被使用)。例如有人可以傳遞指向它的指針,這些指針是可編譯的,但會產生不好的結果。 – LihO 2013-03-22 16:51:11

2

嘗試用gcc -E建立你的代碼,看看編譯它

實際上在構建過程中compilator之前,你的代碼看看如何改變你的實際代碼爲預處理程序代碼。 在預處理階段compilator替換其內容的C代碼的所有宏,並生成另一個代碼稱爲預處理代碼,然後compilateor產生來自前處理代碼的對象代碼

gcc -E讓你看到你的預處理器代碼

+0

哦,我明白了。我知道這不是一個實際的功能,但我對它是如何操作感到困惑。感謝您解決這個問題。 – PresidentRFresh 2013-03-22 16:44:18

+0

不客氣 – MOHAMED 2013-03-22 16:45:05

4

什麼編譯器實際看到,預處理後,就是:

int i = ((4)>(5)) ? (4):(5)); 

傳遞給宏參數代入宏的身體。

3

只是停止思考像編譯代碼宏。宏由預處理器「解決」,而不是在編譯階段。因此,通過宏定義,您只需定義如何處理文本文件中的某些字符串。只有預處理器的輸出傳遞給編譯器。您可以使用gcc -E在預處理器後查看源代碼。在這個階段它仍然是C代碼,但沒有任何預處理指令。

希望這會幫助你。