logo

C-Präprozessoren

Präprozessoren sind Programme, die den Quellcode verarbeiten, bevor mit der eigentlichen Kompilierung begonnen wird. Sie sind nicht Teil des Kompilierungsprozesses, sondern arbeiten separat, sodass Programmierer den Code vor der Kompilierung ändern können.

  • Dies ist der erste Schritt, den der C-Quellcode durchläuft, wenn er in eine ausführbare Datei konvertiert wird.
  • Die wichtigsten Arten von Präprozessoranweisungen sind  Makros Bedingte Kompilierung der Dateieinbindung und andere Anweisungen wie #undef #pragma usw.
  • Hauptsächlich werden diese Anweisungen verwendet, um einen bestimmten Abschnitt des C-Codes durch einen anderen C-Code zu ersetzen. Wenn wir beispielsweise „#define PI 3.14“ schreiben, wird PI vom Präprozessor durch 3.14 ersetzt.
C-Präprozessoren

Arten von C-Präprozessoren

Alle oben genannten Präprozessoren können in 4 Typen eingeteilt werden:

Makros

Makros werden verwendet, um Konstanten zu definieren oder Funktionen zu erstellen, die vom Präprozessor ersetzt werden, bevor der Code kompiliert wird. Die beiden Präprozessoren #definieren Und #undef werden zum Erstellen und Entfernen von Makros in C verwendet.



#definieren Token-Wert
#undef Token

wobei nach der Vorverarbeitung die Token wird auf seine erweitert Wert im Programm.

Beispiel:

C
#include  // Macro Definition #define LIMIT 5 int main(){  for (int i = 0; i < LIMIT; i++) {  printf('%d n' i);  }  return 0; } 

Ausgabe
0 1 2 3 4 

Im obigen Programm wird vor Beginn der Kompilierung das Wort LIMIT durch 5 ersetzt. Das Wort 'LIMIT' in der Makrodefinition wird als Makrovorlage bezeichnet Und „5“ ist Makroexpansion.

Notiz Am Ende der Makrodefinition steht kein Semikolon (;). Makrodefinitionen benötigen am Ende kein Semikolon.

Es gibt auch welche Vordefinierte Makros in C die bei der Bereitstellung verschiedener Funktionalitäten für unser Programm nützlich sind.

Ein zuvor definiertes Makro kann mit dem Präprozessor #undef dedefiniert werden. Zum Beispiel im obigen Code

C
#include  // Macro Definition #define LIMIT 5 // Undefine macro #undef LIMIT int main(){  for (int i = 0; i < LIMIT; i++) {  printf('%d n' i);  }  return 0; } 


Ausgabe:

./Solution.c: In function 'main': ./Solution.c:13:28: error: 'MAX' undeclared (first use in this function) printf('MAX is: %dn' MAX); ^ ./Solution.c:13:28: note: each undeclared identifier is reported only once for each function it appears in

Makros mit Argumenten

Wir können auch Argumente an Makros übergeben. Diese Makros funktionieren ähnlich wie Funktionen. Zum Beispiel

# definieren foo(a b) a + b
#define func(r) r * r

Lassen Sie uns dies mit einem Programm verstehen:

C
#include  // macro with parameter #define AREA(l b) (l * b) int main(){  int a = 10 b = 5;    // Finding area using above macro  printf('%d' AREA(a b));  return 0; } 

Ausgabe
Area of rectangle is: 50 

Erläuterung: Im obigen Programm das Makro FLÄCHE(l b) ist definiert, um die Fläche eines Rechtecks ​​durch Multiplikation seiner Fläche zu berechnen Länge (l) Und Breite (b) . Wann BEREICH(a b) heißt es erweitert sich zu (a * b) und das Ergebnis wird berechnet und gedruckt.

Bitte beziehen Sie sich auf Arten von Makros in C für weitere Beispiele und Typen.

Java-Ganzzahl

Dateieinbindung

Durch die Dateieinbindung können Sie externe Dateien (Header-Dateibibliotheken usw.) in das aktuelle Programm einbinden. Dies geschieht normalerweise mit dem #enthalten Direktive, die sowohl System- als auch benutzerdefinierte Dateien enthalten kann.

Syntax

Es gibt zwei Möglichkeiten, Header-Dateien einzubinden.

#enthalten
#enthalten 'Dateiname'

Der '<' Und '>'-Klammern Weisen Sie den Compiler an, nach der Datei in zu suchen Standardverzeichnis während doppelte Anführungszeichen ( ' ' ) Weisen Sie den Compiler an, im Verzeichnis der Quelldatei nach der Header-Datei zu suchen.

Beispiel:

C
// Includes the standard I/O library #include   int main() {  printf('Hello World');    return 0; } 

Ausgabe
Hello World

Bedingte Kompilierung

Bedingte Kompilierung ermöglicht es Ihnen, abhängig von bestimmten Bedingungen Teile des Codes einzuschließen oder auszuschließen. Dies ist nützlich zum Erstellen von plattformspezifischem Code oder zum Debuggen. Es gibt die folgenden bedingten Präprozessoranweisungen: #if #ifdef #ifndef else #elif und #endif

Syntax

Die allgemeine Syntax bedingter Präprozessoren lautet:

#Wenn
// etwas Code
#elif
// noch etwas Code
#anders
// Etwas mehr Code
#endif

Die Direktive #endif wird verwendet, um die Eröffnungsdirektiven #if #ifdef und #ifndef zu schließen.

Beispiel

C
#include  // Defining a macro for PI #define PI 3.14159 int main(){   // Check if PI is defined using #ifdef #ifdef PI  printf('PI is definedn'); // If PI is not defined check if SQUARE is defined #elif defined(SQUARE)  printf('Square is definedn'); // If neither PI nor SQUARE is defined trigger an error #else  #error 'Neither PI nor SQUARE is defined' #endif // Check if SQUARE is not defined using #ifndef #ifndef SQUARE  printf('Square is not defined'); // If SQUARE is defined print that it is defined #else  printf('Square is defined'); #endif  return 0; } 

Ausgabe
PI is defined Square is not defined

Erläuterung: Dieser Code verwendet bedingte Präprozessoranweisungen ( #ifdef #elif und #ifndef ), um zu prüfen, ob bestimmte Makros ( PI Und QUADRAT ) definiert sind. Da PI definiert ist, gibt das Programm Folgendes aus: PI ist definiert ' prüft dann, ob SQUARE nicht definiert ist und gibt aus ' Quadrat ist nicht definiert '.

Andere Richtlinien

Neben den primären Präprozessoranweisungen stellt C auch andere Anweisungen zur Verwaltung des Compilerverhaltens und zum Debuggen bereit.

#pragma:

Stellt dem Compiler spezifische Anweisungen zur Steuerung seines Verhaltens zur Verfügung. Es wird verwendet, um Warnungen, Einstellungsausrichtung usw. zu deaktivieren.

Syntax

#pragma Richtlinie

Einige der #pragma-Anweisungen werden im Folgenden erläutert: 

  1. #pragma-Startup: Mithilfe dieser Anweisungen können wir die Funktionen angeben, die vor dem Programmstart ausgeführt werden müssen (bevor die Steuerung an main() übergeht).
  2. #pragma-Exit : Diese Anweisungen helfen uns, die Funktionen anzugeben, die unmittelbar vor dem Beenden des Programms ausgeführt werden müssen (kurz bevor die Steuerung von main() zurückkehrt).

Beispiel

C
#include  void func1(); void func2(); // specifying funct1 to execute at start #pragma startup func1 // specifying funct2 to execute before end #pragma exit func2 void func1() { printf('Inside func1()n'); } void func2() { printf('Inside func2()n'); } int main(){  void func1();  void func2();  printf('Inside main()n');  return 0; } 

Ausgabe
Inside main() 

Der obige Code erzeugt die oben angegebene Ausgabe, wenn er auf GCC-Compilern ausgeführt wird, während die erwartete Ausgabe war:

Erwartete Ausgabe

Inside func1() Inside main() Inside func2() 

Dies liegt daran, dass GCC das Starten oder Beenden von #pragma nicht unterstützt. Sie können jedoch den folgenden Code für die erwartete Ausgabe auf GCC-Compilern verwenden. 

C
#include  void func1(); void func2(); void __attribute__((constructor)) func1(); void __attribute__((destructor)) func2(); void func1() {  printf('Inside func1()n'); } void func2() {  printf('Inside func2()n'); } int main() {  printf('Inside main()n');  return 0; } 

Ausgabe
Inside func1() Inside main() Inside func2() 

Im obigen Programm haben wir einige verwendet spezifische Syntaxen sodass eine der Funktionen vor der Hauptfunktion und die andere nach der Hauptfunktion ausgeführt wird.

Quiz erstellen