2013-06-02 34 views
0

我正在閱讀一些C的代碼,並被卡在這裏。有條件的衍生產品 - #define in C

下面你會發現頭文件中的代碼片段。

#if NUMREPS == 0 
     #define REPEAT(line) REPEAT0(line); 
#elif NUMREPS == 16 
     #define REPEAT(line) REPEAT16(line); 
#endif 

而對於標識repeat16(line);的導數定義如下:

#define REPEAT16(line) \ 
    line;\ 
    line;\ 
    line;\ 
    line;\ 
    line;\ 
    line;\ 
    line;\ 
    line;\ 
    line;\ 
    line;\ 
    line;\ 
    line;\ 
    line;\ 
    line;\ 
    line;\ 
    line; 

這究竟編碼片段嗎? 我幫助了link瞭解代碼

+0

哪一部分是令人費解你:

此使用宏時定義整函數經常使用呢? –

+0

'line'到底是做什麼用的? – pistal

+0

使用'gcc -C -E sourcecode.c> sourcecode.i'獲取預處理的表單'sourcecode.i'。然後用分頁器('less sourcecode.i')或編輯器('emacs sourcecode.i')查看它。 –

回答

6

預處理器是在實際編譯之前運行的編譯過程的一個步驟。它對宏的作用僅僅是將宏調用替換爲宏的主體。所以當預處理器看到REPEAT16的「調用」時,它將簡單地用宏的參數代替它,重複16次,如同在主體中一樣。

的說法line正是你傳遞到宏觀的東西,因此,如果您例如稱呼它

REPEAT16(printf("hello\n")) 

那麼編譯器看到的代碼將

printf("hello\n"); printf("hello\n"); printf("hello\n"); printf("hello\n"); printf("hello\n"); printf("hello\n"); printf("hello\n"); printf("hello\n"); printf("hello\n"); printf("hello\n"); printf("hello\n"); printf("hello\n"); printf("hello\n"); printf("hello\n"); printf("hello\n"); printf("hello\n"); 

中的\字符宏體只是告訴預處理器當前的行繼續下一個。所以整個身體將是一條線。

+0

只是一個天真的問題:這是否意味着它假定沒有新行字符?' – pistal

+3

可能值得注意的是'if(false)REPEAT16(printf(「hello \ n」)); '會打印'你好'15次。 –

+0

@ user2015933不,預處理器不會添加任何換行符。宏體必須是單行,而使用'\'是將多行宏體連接成單行。 –

4

行末尾的反斜槓(\)被預處理器替換爲以下行。

這是一種編寫多行宏定義的常用方法,因爲替換文本必須位於單個「邏輯」行中,所以使用續行來使其更容易閱讀。

#define INT_RETURNER(x) int return_ ## x (void)\ 
         {\ 
          return x;\ 
         } 

INT_RETURNER(4711) 

int main(void) 
{ 
    printf("%d!\n", return_4711()); 
} 
+0

爲什麼替換文本需要在一條邏輯線上? – pistal

+0

@ user2015933因爲宏不能跨越多個邏輯行。我相信這個標準有更準確的語言,但這是基礎。 –