2013-10-05 11 views
11

Ich habe ein Programm.Was macht '#' genau 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; 
} 

Dieses Programm korrekt funktioniert und geben Ausgang als:

12 
f(1, 2) 

Ich verstehe nicht, wie Compiler diese Ausgabe zu geben. Wie lautet die Funktion von # in a##b und ?

+0

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

+0

@YuHao, ich bin wirklich leid . Ich habe nach dieser Frage gesucht. Ich habe keine Verwandten bekommen. weil ich nicht weiß # heißt stringify. – SGG

+0

@SGG Hey, das ist in Ordnung, weil es schwierig ist, nach dieser Frage zu suchen, da es kein bestimmtes Keyword gibt. Ich erinnere mich, dass ich dieses Programm schon einmal gesehen hatte und immer noch einige Minuten damit verbracht habe, das Duplikat zu finden :) Selbst wenn man die grundlegende Verwendung von '#' und '##' kennt, ist diese Frage immer noch schwer zu bekommen. –

Antwort

4

lassen Sie mich es für Sie brechen:

#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

Im Allgemeinen richtig, aber nach (1) kommt zuerst die 'h()' Definition als (2), die wiederum "f()" aktiviert, was (3) und dann 'g()' (4). – glglgl

12

Die ## verkettet zwei Token zusammen.

Wichtig ist, dass es nur im Präprozessor verwendet werden kann.

Der Operator # wird zum Beschriften von Tokens verwendet.

Zum Beispiel: -

#(a ## b) die #ab wird, die wird "ab"

So h (f (1,2)) wird "f (1,2)"

Beachten Sie auch, dass und ## zwei verschiedene Operatoren sind.

Der Präprozessor Operator ## bietet eine Möglichkeit, tatsächliche Argumente während Makroerweiterung zu verketten. Wenn ein Parameter im Ersatztext an ein ## angrenzt, wird der Parameter durch das tatsächliche Argument ersetzt, das ## und der umgebende Leerraum werden entfernt und das Ergebnis wird erneut gescannt.

Überprüfen Sie auch diese Concatenation für weitere Details.

Von here: -

Stringification

Manchmal möchten Sie ein Makro-Argument in einen String konstant konvertieren. Parameter werden nicht innerhalb von Stringkonstanten ersetzt, aber Sie können den '#' Vorverarbeitungsoperator statt verwenden. Wenn ein Makroparameter mit einem führenden '#' verwendet wird, ersetzt der Präprozessor ihn durch den Literaltext des tatsächlichen Arguments, konvertiert in eine String-Konstante. Im Gegensatz zum normalen Parameteraustausch wird das Argument nicht zuerst macro-expanded. Dies wird als Stringifizierung bezeichnet.

Es gibt keine Möglichkeit, ein Argument mit dem umgebenden Text zu kombinieren und alles zusammen zu stringifizieren. Stattdessen können Sie eine Reihe von Zeichenfolgenkonstanten und stringifizierten Argumenten schreiben. Der Präprozessor ersetzt die stringifizierten Argumente durch String-Konstanten.Der C Compiler wird dann alle benachbarten String-Konstanten in eine lange Zeichenfolge kombinieren.

+0

+1 Sie können erwähnen, dass '#' und '##' zwei verschiedene Operatoren sind. – dasblinkenlight

+0

Warum der Unterschied in den Ergebnissen, wenn wir fast identische Anrufe haben? – this

+1

@self. Wie sind sie "fast identisch"? 2 * 12 und 2 + 12 sind ebenfalls "fast identisch" und ergeben völlig unterschiedliche Ergebnisse. – glglgl

4

## wird „token-Einfügen“ -Operator oder „merging“ Operator genannt, die verwendet werden können zwei Token zu kombinieren, um ein tatsächliches Argument zu bilden.

# heißt Stringizing Operator, der "Makroparameter in String-Literale konvertiert, ohne die Parameterdefinition zu erweitern".

Diese werden allgemein Präprozessoroperatoren genannt. Es gibt einige weitere Präprozessoroperatoren wie diese. Weitere Informationen finden Sie in Präprozessoroperatoren in C (http://msdn.microsoft.com/en-us/library/wy090hkc.aspx).


Kasse Auch http://msdn.microsoft.com/en-us/library/3sxhs2ty.aspx und der „siehe auch“ Abschnitt dieser Seite für weitere Informationen über C Preprocessor.