2013-10-05 11 views
11

Ho un programma.Cosa fa esattamente # in C?

#include <stdio.h> 

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

int main() 
{ 
     printf("%s\n",h(f(1,2))); 
     printf("%s\n",g(f(1,2))); 
     return 0; 
} 

Questo programma funziona correttamente e dando uscita come:

12 
f(1, 2) 

Non capisco come compilatore dando questa uscita.

Qual è la funzione di # in a##b e #a?

+0

http://stackoverflow.com/questions/16989730/c-stringify-how-does-it-work –

+0

@YuHao, mi dispiace davvero . Ho cercato questa domanda. Non ho avuto alcuna relazione. perché non so # si chiama stringify. – SGG

+0

@SGG Ehi, va bene perché è difficile cercare questa domanda perché non ci sono parole chiave particolari. Ricordo di aver visto questo programma in passato e di aver speso diversi minuti per trovare il duplicato :) Pur conoscendo l'uso di base di '#' e '##', questa domanda è ancora difficile da ottenere. –

risposta

4

cerchiamo di scomposizione per voi:

#define f(a,b) a##b //2 this macro is evaluated first with a = 1 and b = 2 it concatenates them and returns 12 
#define g(a) #a //4 g turns 12 into "12" (string) 
#define h(a) g(a) //3 back to h which now has a = 12 and call g() 

int main() 
{ 
     printf("%s\n",h(f(1,2)));//1 printf calls the macro h() and gives it the macro f() as an argument 
     printf("%s\n",g(f(1,2)));// g here turns f(1,2) into "f(1,2)" (string) 
     return 0; 
} 
+0

Generalmente a destra, ma dopo (1) viene prima la definizione di 'h()' come (2), che a sua volta "attiva" 'f()', che sarebbe (3) e poi 'g()' (4). – glglgl

12

Il numero ## concatena due token insieme.

L'importante è che possa essere utilizzato solo nel preprocessore.

L'operatore # è utilizzato per stringificare i token.

Ad esempio: -

#(a ## b) che diventa #ab che diventa "ab"

Quindi h (f (1,2)) diventa "f (1,2)"

noti inoltre che # e ## sono due operatori diversi.

L'operatore preprocessore ## fornisce un modo per concatenare reali argomenti durante macro espansione. Se un parametro nel testo di sostituzione è adiacente a ##, il parametro viene sostituito dall'argomento effettivo, il ## e lo spazio bianco circostante vengono rimossi e il risultato viene rieseguito.

controllare anche questo Concatenation per maggiori dettagli.

Da here: -

Forzare a stringa

volte può essere utile per convertire un argomento di macro in una stringa costante. I parametri non vengono sostituiti all'interno delle costanti stringa, ma è possibile utilizzare l'operatore di pre-elaborazione "#" anziché. Quando un parametro macro viene utilizzato con un "#" iniziale, il preprocessore lo sostituisce con il testo letterale dell'argomento effettivo, convertito in costante di stringa. Diversamente dalla normale sostituzione dei parametri, l'argomento non è la macro espansa . Questo è chiamato stringificazione.

Non esiste alcun modo per combinare un argomento con il testo circostante e stringificarlo tutto insieme. Invece, è possibile scrivere una serie di costanti di stringa adiacenti e argomenti con stringhe. Il preprocessore sostituirà gli argomenti con stringhe con costanti stringa.Il compilatore C combina quindi tutte le costanti di stringa adiacenti in una stringa lunga .

+0

+1 Potresti voler dire che '#' e '##' sono due operatori diversi. – dasblinkenlight

+0

Perché la differenza nei risultati se abbiamo chiamate quasi identiche? – this

+1

@ self. Come sono "quasi identici"? Anche 2 * 12 e 2 + 12 sono "quasi identici" e producono risultati completamente diversi. – glglgl

4

## operatore è chiamato "token incolla", o l'operatore "fusione", che può essere usato per combinare due gettoni per formare un argomento effettivo.

si chiama Stringizing Operator che "converte i parametri macro in string letterali senza espandere la definizione del parametro".

Questi sono generalmente denominati Operatori di preprocessore. Esistono altri operatori di preprocessore come questi. Consulta Operatori di preprocessore in C (http://msdn.microsoft.com/en-us/library/wy090hkc.aspx) per ulteriori spiegazioni.


checkout anche http://msdn.microsoft.com/en-us/library/3sxhs2ty.aspx e la sezione "vedi anche" di quella pagina per ulteriori informazioni su C preprocessore.