2009-11-06 51 views
6

什麼是a##b & #a這個C代碼是如何工作的?

#define f(a,b) a##b 
    #define g(a) #a 
    #define h(a) g(a) 

    main() 
    { 
      printf("%s\n",h(f(1,2))); //how should I interpret this?? [line 1] 
      printf("%s\n",g(f(1,2))); //and this? [line 2] 
    } 

該程序如何工作?


輸出是

12 
f(1, 2) 

現在我明白瞭如何a##b & #a工作。 但是爲什麼在兩種情況下(第1行和第2行)的結果不同?

+3

當你運行該程序時會發生什麼?這樣做應該可以幫助你瞭解正在發生的事情。 – 2009-11-06 09:02:53

+1

真的,用這段代碼玩一會兒就會發光。如果您有任何具體問題,請隨時在這裏問問他們。 – sharptooth 2009-11-06 09:04:38

回答

19

##將兩個令牌連接在一起。它只能用於預處理器。

f(1,2)變成1 ## 2變成12

#運營商本身字符串化令牌:#a變成"a"。因此,g(f(1,2))變成"f(1,2)"當預處理器完成它。

h(f(1,2))實際上是#(1 ## 2)它變成#12它變成"12"當預處理器運行它時。

4

一個## B就togather粘貼代碼。

so f(1,2)將變爲12

+2

這只是問題的一半。 – 2009-11-06 09:06:05

0

一個## b是文字a和b的串contatenation,因此f(1,2)爲 「12」

#A是字符串文字一個,所以克(3)爲 「3」

3

在F(A,b)宏會將其參數,G(A)變爲其參數爲一個字符串和h(a)是用於克輔助宏(a)中。我認爲這將輸出:

12 
f(1,2) 

的原因是H(一)宏將導致其參數是完全將其傳遞到G前擴大(一),而G(A)會從字面上採取它的參數不擴大他們第一。

+0

爲什麼第二個printf在'「f(1,2)」'而不是'「12」'中結束? – Moeb 2009-11-06 09:11:56

+0

爲什麼會發生這種情況:'「原因是h(a)宏在將它的參數傳遞給g(a)之前會使其參數完全展開,而g(a)將直接採用它的參數,而不會首先展開它們。」' ? – Moeb 2009-11-06 09:13:03

0

##是宏連接運算符。因此,例如f(foo,bar)將相當於foobar

5

對於像這樣的問題(以及更多與預處理器有關的「現實世界」問題),我發現實際讀取代碼之後已被預處理非常有幫助。

如何做到這一點的編譯器有所不同,但用gcc,你這樣做:

$ gcc -E test.c 

(snip) 
main() 
{ 
     printf("%s\n","12"); 
     printf("%s\n","f(1,2)"); 
} 

所以,你可以看到符號已經二​​者連接,並且變成了一個字符串。

+0

爲什麼第二個printf在'「f(1,2)」'而不是'「12」'中結束? – Moeb 2009-11-06 09:11:04

+0

@hanifr:因爲g()宏將其參數串化,我猜。 – unwind 2009-11-06 09:22:47

0
 
    #define f(a,b) a##b 
    #define g(a) #a 
    #define h(a) g(a) 

所以,##組合2件直接在一起,不管它們是什麼類型的? 給你一個例子.. printf("%d\n",f(1,2));你12,這意味着這裏F(1,2)是12一個整數。

 
    int a2 = 100; 
    printf("%d\n",f(a,2)); 

這裏f(a,2)是標籤。它指向代碼上下文中的標籤,如果不存在int a2 = 100,則會出現編譯錯誤。 而#a輪流任何一個是,爲一個字符串... 然後h(a) g(a) 這是非常奇怪.. 看來,當你調用H(A),它變成G(A),並傳遞到克( a),首先,它解釋什麼是。所以,在g(a)之前,a被轉換爲f(a,b)= a ## b = 12