2017-12-03 395 views
1

如何將宏參數和另一個整型變量一起傳遞給宏函數? 將宏參數傳遞給宏函數

#define SUM(X, Y, Z) X + Y + Z 
#define FOO 1, 2 

void print(int a, int b) 
{ 
    printf("Sum: %d", a + b); 
} 

int main(void) 
{ 
    // Normal function works as expected 
    print(FOO); 

    // Macro function not working 
    int a = 3; 
    printf("\nMacro Sum: %d", SUM(FOO, a)); 

    return 0; 
} 

我期望的輸出是:

Sum: 3 
Macro Sum: 6 

不過,我得到以下錯誤:

main.c:18:41: error: macro "SUM" requires 3 arguments, but only 2 given 
    printf("\nMacro Sum: %d", SUM(FOO, a)); 
+0

當您使用SUM(FOO,a)'展開該行時,直到參數確定後纔會展開FOO。只有2個參數,但宏觀預期3 - 因此消息。接下來會發生'FOO'擴展爲'1,2'的情況。 –

回答

0

單宏參數會的工作:

#define SUM(X, Y, Z) X + Y + Z 
#define FOO1 (1) 
#define FOO2 (2) 

void print(int a, int b) 
{ 
    printf("Sum: %d", a + b); 
} 

int main(void) 
{ 
    // Normal function works as expected 
    print(FOO1,FOO2); 

    int a = 3; 
    printf("\nMacro Sum: %d", SUM(FOO1, FOO2, a)); 

    return 0; 
} 

輸出:

Sum: 3 
Macro Sum: 6 
1

當宏分析被解析時,宏參數不會被擴展。在宏調用被分析之後,宏定義文本中的每個宏參數的使用都將被宏擴展參數替代,除了與###操作(stringify和令牌粘貼)一起使用的宏參數(用參數宏觀參數的未擴展文本。然後執行###操作,然後再次掃描整個宏體。

結果是SUM(FOO, a)被解析爲有兩個參數。由於宏需要三個,所以不會編譯。

可以解決這個問題,在一定程度上,通過使用宏擴展的一個額外的級別:

#define CALL(macro, ...) macro(__VA_ARGS__) 

printf("\nMacro Sum: %d", CALL(SUM, FOO, a)); 

現在使用__VA_ARGS__參數(這恰好是一個可變參數的參數,雖然這使得絕對的與擴展順序沒有什麼區別)將在替換文本重新掃描之前展開,因此將使用三個參數調用FOO


順便說一句,在輸出的輸出行的開頭一個換行符是一個壞習慣,這將讓你陷入困境的一天。輸出線應該有一個換行符在該行的末尾:

printf("Macro Sum: %d\n", CALL(SUM, FOO, a)); 

這沒有什麼錯寫一個空行預先放一個換行符在最開始也就是,但無論如何,你應該總是用\n終止outpur線。否則:

  1. 該行可能不會立即寫入。在發送換行符之前,行緩衝輸出實際上不會發送到輸出設備/文件。

  2. 如果程序是一個控制檯應用程序,並且在沒有正確關閉的情況下終止stdout,您會發現自己正在鍵入下一個shell命令,如果是最後一個輸出行。這往往會混淆線路編輯輸入庫,如readline