2012-10-19 11 views
5

Ich versuche, den Unterschied zwischen einem typedef zu verstehen und definieren. Es gibt viele gute Beiträge speziell bei this previous question on SO, jedoch kann ich die Post nicht verstehen, dassWas bedeutet Vorverarbeitung genau in Compiler

heißt

#define ein Präprozessor-Token ist: der Compiler selbst wird es nie sehen.
typedef ist ein Compiler-Token: der Präprozessor überhaupt nicht darum kümmern.

Könnte jemand bitte dies mit ein wenig mehr Details erklären. Ich bin hier mit dem Begriff Präprozessor verwechselt.

Antwort

5

Der Pre-Prozessor ist ein Programm, das vor den Compiler ausführt und Textsubstitution im Wesentlichen ausführt. Wenn Sie schreiben:

#define X 10 

int main() 
{ 
    int x = X; 
} 

Der Vorprozessor diese Datei als Eingabe, tut es Sache ist, und Ausgänge:

int main() 
{ 
    int x = 10; 
} 

Und dann der Compiler macht seine Sache mit dem vorverarbeiteten Ausgang.

typedef auf der anderen Seite ist ein Konstrukt, das der Compiler versteht. Wenn Sie schreiben:

typedef unsigned int uint_32; 

Der Compiler weiß, dass uint32 für unsigned int tatsächlich ein Alias ​​ist. Dieser Alias ​​wird vom Compiler selbst gehandhabt und beinhaltet etwas mehr Logik als die einfache Textersetzung. Deutlich wird dies mit einem einfachen Beispiel:

typedef int my_int; 

int main() 
{ 
    unsigned my_int x; // oops, error 
} 

Wenn ein typedef ein einfacher Textsubstitutionsmechanismus sind (wie der Pre-Prozessor ist), dann das funktionieren würde, aber es ist nicht erlaubt und wird nicht kompilieren.

5

Ein Präprozessor ist eine Phase, die, bevor sie eine Kompilation auftritt beginnt. Es liest bestimmte Makros und Symbole, die ersetzt werden sollen. Es ist normalerweise ein bis zwei Passagen. Es scannt die gesamte Quelldatei und generiert eine Symboltabelle, um Makros zu ersetzen oder zu erweitern.

Nachdem alle Substitutionen vorgenommen wurden, übernimmt der Syntaxanalysator das Lexing-Parsing der Quelldatei, generiert abstrakte Syntaxbäume, generiert Code, verknüpft Bibliotheken und generiert ausführbare Dateien/Binärdateien.

In C/C++/ObjC Präprozessor DIREKTIVEN beginnen mit '#' gefolgt von dem Namen der Anweisung wie "definieren", "ifdef", "ifndef", "elif", "if", "endif" usw.

VOR PREPROCESSING:

#define TEXT_MACRO(x) L##x 
#define RETURN return(0) 
int main(int argc, char *argv[]) 
{ 
    static wchar_t buffer[] = TEXT_MACRO("HELLO WORLD"); 
    RETURN ; 
} 

nACH VORBEHANDLUNG:

int main(int argc, char *argv[]) 
{ 
    static wchar_t buffer[] = L"HELLO WORLD"; 
    return (0); 
} 

Wenn ich mich richtig erinnere, das Buch "The C Programming Language" 2. Auflage, von Kernighan und Ritchie ein Beispiel hat, wo sie zeigen, ho w um einen eigenen VORBEREITER zu erstellen und wie es funktioniert. Auch der Plan9 C Compiler trennte die beiden Prozesse (Kompilierung und Vorverarbeitung). Damit können Sie Ihren eigenen PREPROCESSOR verwenden.

Check out An interesting preprocessor for multiple languages und Write your own pre-processor. die Eingabe und Ausgabe dieser Programme zu sehen, gibt Ihnen ein tieferes Verständnis dessen, was ein Präprozessor tatsächlich ist.

Ein weiterer kleines Geheimnis: Sie können in C-Code Latin/Deutsch/Spanisch, wenn Sie einen Präprozessor haben :)

+0

Danke, dass hilft – Murphy316

+0

+1 Richtige Antwort und Sie gaben es zuerst. Ein Beispiel wäre aber nett. – Alex

+0

Ein Beispiel wäre schön gewesen – Murphy316

2

Wenn es um die Zusammenstellung kommt, Pass des Quellcodes durch eine Menge Schritt. In diesem Schritt gibt es Vorverarbeitung.

Der Präprozessor-Programm, das vor dem Compiler ausgeführt wird, und führen Sie alle # begann Anweisungen, wie #include, #define, etc ..

In Ihrem speziellen Fall, #define WORD newword ist eine Richtlinie, die sagt: „alle Vorkommen ersetzen von WORD mit newword ", bevor man sogar versucht, das Programm zu kompilieren.

Wenn Sie es in Aktion sehen möchten, versuchen Sie, cpp file.c ausführen und untersuchen Sie die Ausgabe, um zu verstehen, was es tut.

Datei.

c
#define WORD "newword" 

int main() 
{ 
    printf("this is word: %s\n", WORD); 
    return 0;       
} 

wird nach cpp werden läuft

int main() 
{ 
    printf("this is word: %s\n", "newword"); 
    return 0; 
} 

typedef, auf der anderen Seite, werden verwendet, zu sagen: "Wenn ich über Type sprechen, verstehen, dass ich meinte struct more_complex_type" Es wird verwendet, zur Kompilierzeit und bleibt vor und nach dem cpp Pass gleich.

2

Ein Präprozessor ist eine "Engine", die ausgeführt wird, bevor der Compiler den Code kompiliert. #define #include sind Präprozessordirektiven oder Makros, also führt die Präprozessor-Engine Code aus, der sich auf die Anweisungen bezieht. Wenn der Präprozessor fertig ist, sieht der Compiler nichts von den Direktiven/Makros. Jedoch werden Konstrukte wie typedef, if, while usw. vom Compiler verstanden.

+0

Im Visual Studio, wenn wir Code schreiben, wird der Präprozessor während der Eingabe ausgeführt (dh nachdem wir einen Präprozessor deklariert haben und versuchen könnten, ihn zu benutzen)? – Murphy316

+0

Es wäre sinnvoll, wenn es so wäre. Sonst wäre das Intellisense nutzlos. –

3

Die C- und C++ - Präprozessoren sind eine logische Phase in der Kompilierung, die sehr früh erfolgt. Der Präprozessor wandelt eine Quelldatei in eine Übersetzungseinheit durch den Text von Header-Dateien enthalten, die, bedingt beseitigen Teile der Dateien durch #include, angegeben sind (#if, #elif, #else, #endif und Varianten #ifdef und #ifndef) und von Makro zu tun Substitutionen. Die Makros werden über #define definiert; Die Makros können vom Präprozessor beim Scannen der Quelle erkannt werden.

Der Präprozessor meisten Linien, die mit # beginnen beseitigt (es bleibt nur #line Richtlinien hinter sich und seine eigene abgekürzten Varianten auf #line hinter dem Compiler zu sagen, wo die Quelle herkommt). Der eigentliche Compiler sieht dann das Ergebnis der Vorverarbeitung und kompiliert den Quellcode, der definiert ist.

Der Präprozessor würde das Wort typedef normalerweise nicht ändern.Ein wahnsinniger Programmierer könnte ein Makro für typedef definieren und der Präprozessor ist vielleicht egal; Der Programmierer konnte keinen Systemheader legitimieren, während ein Makro mit demselben Namen definiert ist wie jedes andere Schlüsselwort in der Sprache. Andernfalls ist typedef ein Problem für den Compiler, nicht der Präprozessor. So ist auch sizeof(); das versteht der Präprozessor nicht.

Normalerweise gibt es Compiler-Optionen, mit denen Sie die vorverarbeitete Ausgabe sehen können. Für gcc sind die Optionen -E und -P.

1

Es bedeutet, dass der Präprozessor vor dem Compiler ausgeführt wird und den Quellcode vor dem Weiterleiten an den Compiler ändert. Daher sieht der Compiler niemals etwas von dem Code. Beispiel:

#define ONE 1 
int x = ONE; 

Wenn Sie diese kompilieren, der Präprozessor verwandelt er sich in diese:

int x = 1; 

und übergibt die neuen Text an den Compiler. Daher sieht der Compiler den Text ONE nicht.