2013-10-05 5 views
11

J'ai un programme.Que fait exactement "#" en 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; 
} 

Ce programme fonctionne correctement et en donnant la sortie comme:

12 
f(1, 2) 

Je ne comprends pas comment compilateur donner cette sortie. Quelle est la fonction de # dans a##b et #a?

+0

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

+0

@YuHao, je suis vraiment désolé . J'ai cherché cette question. Je n'ai pas eu de relation. parce que je ne sais pas # est appelé stringify. – SGG

+0

@SGG Hé, c'est bien parce qu'il est difficile de chercher cette question car il n'y a pas de mot-clé particulier. Je me souviens avoir vu ce programme auparavant et j'ai encore passé plusieurs minutes à trouver le doublon :) Même en connaissant l'utilisation basique de '#' et '##', cette question est encore difficile à obtenir. –

Répondre

4

laissez-moi le décomposer pour vous:

#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

Généralement juste, mais après (1) vient d'abord la définition 'h()' comme (2), qui à son tour "active" 'f()', ce qui serait (3) et ensuite 'g()' (4). – glglgl

12

Les ## Assemble deux jetons ensemble.

L'important est qu'il ne peut être utilisé dans le préprocesseur.

L'opérateur # est utilisé pour stringify jetons.

Par exemple: -

#(a ## b) qui devient #ab qui devient "ab"

donc h (f (1,2)) devient "f (1,2)"

Notez également que # et ## sont deux opérateurs différents.

L'opérateur préprocesseur ## fournit un moyen de concaténer réels arguments lors de l'expansion macro. Si un paramètre dans le remplacement texte est adjacent à un ##, le paramètre est remplacé par l'argument réel, on élimine les ## et entourant l'espace blanc, et le résultat est rebalayés.

Vérifiez également ce Concatenation pour plus de détails.

De here: -

La mise en chaîne

Parfois, vous voudrez peut-être convertir un argument macro dans une chaîne constante. Les paramètres ne sont pas remplacées à l'intérieur des constantes de chaîne, mais vous pouvez utiliser l'opérateur de pré-traitement « n » à la place. Lorsqu'un macro-paramètre est utilisé avec un '#' en tête, le préprocesseur le remplace par le texte littéral de l'argument réel, converti en une constante chaîne. Contrairement au remplacement normal des paramètres, l'argument n'est pas macro-développé en premier. C'est ce qu'on appelle la stringification.

Il n'y a aucun moyen de combiner un argument avec le texte environnant et stringify tous ensemble. Au lieu de cela, vous pouvez écrire une série de constantes de chaîne adjacentes et des arguments stringifiés. Le préprocesseur remplace les arguments stringifiés par des constantes de chaîne.Le compilateur C va alors combiner toutes les constantes de chaîne adjacentes en une chaîne longue .

+0

+1 Vous pouvez mentionner que # # et ## sont deux opérateurs différents. – dasblinkenlight

+0

Pourquoi la différence dans les résultats si nous avons des appels presque identiques? – this

+1

@self. Comment ils sont "presque identiques"? 2 * 12 et 2 + 12 sont également "presque identiques" et produisent des résultats complètement différents. – glglgl

4

## est appelé opérateur « coller-jeton », ou un opérateur « de fusion », qui peut être utilisé pour combiner deux jetons pour former un argument réel.

# est appelé Stringizing Operator qui "convertit les paramètres de macro en littéraux de chaîne sans étendre la définition du paramètre".

Ils sont généralement appelés opérateurs de préprocesseur. Il existe quelques opérateurs de préprocesseur plus comme ceux-ci. Consultez les opérateurs de préprocesseur dans C (http://msdn.microsoft.com/en-us/library/wy090hkc.aspx) pour plus d'explications.


Existe aussi http://msdn.microsoft.com/en-us/library/3sxhs2ty.aspx et « voir aussi » section de cette page pour plus d'informations sur préprocesseur C.