Som namnet antyder är preprocessorer program som bearbetar vår källkod före kompilering. Det finns ett antal steg mellan att skriva ett program och exekvera ett program i C/C++. Låt oss ta en titt på dessa steg innan vi faktiskt börjar lära oss om Preprocessorer.

Du kan se de mellanliggande stegen i diagrammet ovan. Källkoden som programmerarna skriver lagras i filen program.c. Denna fil bearbetas sedan av preprocessorer och en expanderad källkodsfil genereras med namnet program. Denna expanderade fil kompileras av kompilatorn och en objektkodsfil genereras med namnet program .obj. Slutligen länkar länkaren denna objektkodsfil till objektkoden för biblioteksfunktionerna för att generera den körbara filen program.exe.

Preprocessorprogram tillhandahåller preprocessordirektiv som talar om för kompilatorn att förbehandla källkoden innan den kompileras. Alla dessa preprocessordirektiv börjar med symbolen ”#” (hash). Symbolen ”#” anger att det uttalande som börjar med # går till preprocessorprogrammet och att preprocessorprogrammet kommer att utföra detta uttalande. Exempel på några preprocessordirektiv är: #include, #define, #ifndef etc. Kom ihåg att symbolen # endast anger en väg till preprocessorn, och att kommandon som include behandlas av preprocessorprogrammet. Exempelvis kommer include att inkludera extra kod i ditt program. Vi kan placera dessa preprocessordirektiv var som helst i vårt program.

Det finns fyra huvudtyper av preprocessordirektiv:

  1. Macros
  2. File Inclusion
  3. Conditional Compilation
  4. Other directives

Låt oss nu lära oss mer om vart och ett av dessa direktiv i detalj.

  • Makroer: Makroer: Makroer är en del av koden i ett program som får ett namn. Närhelst kompilatorn stöter på detta namn ersätter kompilatorn namnet med den faktiska delen av koden. Direktivet ”#define” används för att definiera ett makro. Låt oss nu förstå makrodefinitionen med hjälp av ett program:
C++

#include <iostream>
#define LIMIT 5
int main()
{
for (int i = 0; i < LIMIT; i++) {
std::cout << i << "\n";
}
return 0;
}



C

#include <stdio.h>
#define LIMIT 5
int main()
{
for (int i = 0; i < LIMIT; i++) {
printf("%d \n",i);
}
return 0;
}



Output:

01234

I ovanstående program ersätter kompilatorn ordet LIMIT med 5 när den utför ordet LIMIT. Ordet ”LIMIT” i makrodefinitionen kallas en makromall och ”5” är en makroexpansion.

Notera: Det finns inget semikolon(’;’) i slutet av makrodefinitionen. Makrodefinitioner behöver inte ha ett semikolon i slutet.

Makroer med argument: Vi kan också skicka argument till makron. Makroer som definieras med argument fungerar på samma sätt som funktioner. Låt oss förstå detta med ett program:

C++

#include <iostream>
#define AREA(l, b) (l * b)
int main()
{
int l1 = 10, l2 = 5, area;
area = AREA(l1, l2);
std::cout << "Area of rectangle is: " << area;
return 0;
}



C

#include <stdio.h>
#define AREA(l, b) (l * b)
int main()
{
int l1 = 10, l2 = 5, area;
area = AREA(l1, l2);
printf("Area of rectangle is: %d", area);
return 0;
}



Output:

Area of rectangle is: 50

Vi kan se från ovanstående program att när kompilatorn hittar AREA(l, b) i programmet ersätter den det med påståendet (l*b) . Inte bara detta, de värden som överlämnats till makromallen AREA(l, b) kommer också att ersättas med påståendet (l*b). Därför kommer AREA(10, 5) att vara lika med 10*5.

  • Filinklusion: Denna typ av preprocessordirektiv talar om för kompilatorn att inkludera en fil i källkodsprogrammet. Det finns två typer av filer som användaren kan inkludera i programmet:
    • Header File eller Standard files: Dessa filer innehåller definitioner av fördefinierade funktioner som printf(), scanf() osv. Dessa filer måste inkluderas för att man skall kunna arbeta med dessa funktioner. Olika funktioner deklareras i olika headerfiler. Exempelvis finns standard I/O-funktioner i ”iostream”-filen medan funktioner som utför strängoperationer finns i ”string”-filen.
      Syntax:
#include< file_name >

där file_name är namnet på den fil som ska inkluderas. Parenteserna ”<” och ”>” talar om för kompilatorn att leta efter filen i standardkatalogen.

  • användardefinierade filer: När ett program blir mycket stort är det bra att dela upp det i mindre filer och inkludera när det behövs. Dessa typer av filer är användardefinierade filer. Dessa filer kan inkluderas som:
#include"filename"
  • Villkorlig kompilering: Villkorliga kompileringsdirektiv är en typ av direktiv som hjälper till att kompilera en viss del av programmet eller att hoppa över kompileringen av en viss del av programmet baserat på vissa villkor. Detta kan göras med hjälp av två förbehandlingskommandon ”ifdef” och ”endif”.
    Syntax:
#ifdef macro_name statement1; statement2; statement3; . . . statementN;#endif

Om makrot med namnet ’macroname’ är definierat kommer blocket av uttalanden att exekveras normalt, men om det inte är definierat kommer kompilatorn helt enkelt att hoppa över detta block av uttalanden.

  • Andra direktiv: Förutom ovanstående direktiv finns det ytterligare två direktiv som inte används så ofta. Dessa är:
    • #undef Direktiv: Direktiven #undef används för att avdefiniera ett befintligt makro. Detta direktiv fungerar på följande sätt:
#undef LIMIT

Användning av det här påståendet kommer att avdefiniera det befintliga makrot LIMIT. Efter detta uttalande kommer varje ”#ifdef LIMIT” uttalande att utvärderas till falskt.

  • #pragma Direktiv: Detta direktiv är ett direktiv för speciella ändamål och används för att aktivera eller inaktivera vissa funktioner. Denna typ av direktiv är kompilatorspecifika, dvs. de varierar från kompilator till kompilator. Några av #pragma-direktiven diskuteras nedan:
    • #pragma startup och #pragma exit: Dessa direktiv hjälper oss att specificera de funktioner som måste köras innan programmet startar (innan kontrollen övergår till main()) och precis innan programmet avslutas (precis innan kontrollen återvänder från main()).
      Notera: Nedanstående program kommer inte att fungera med GCC-kompilatorer.
      Se på nedanstående program:
C++

#include <bits/stdc++.h>
using namespace std;
void func1();
void func2();
#pragma startup func1
#pragma exit func2
void func1()
{
cout << "Inside func1()\n";
}
void func2()
{
cout << "Inside func2()\n";
}
int main()
{
void func1();
void func2();
cout << "Inside main()\n";
return 0;
}



C

#include <stdio.h>
void func1();
void func2();
#pragma startup func1
#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;
}



Uppdrag:

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

Ovanstående kod kommer att ge följande resultat när den körs på GCC-kompilatorer:

Inside main()

Detta beror på att GCC inte stöder #pragma startup eller exit. Du kan dock använda nedanstående kod för att få ett liknande resultat på GCC-kompilatorer.

C

#include <stdio.h>
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;
}



  • #pragma warn Direktiv: Detta direktiv används för att dölja de varningsmeddelanden som visas under kompileringen.
    Vi kan dölja varningarna på följande sätt:
    • #pragma warn -rvl:
    • #pragma warn -par: Detta direktiv döljer de varningar som visas när en funktion som ska returnera ett värde inte returnerar ett värde.
    • #pragma warn -par: Detta direktiv döljer de varningar som visas när en funktion som ska returnera ett värde inte returnerar ett värde: Detta direktiv döljer de varningar som kommer upp när en funktion inte använder de parametrar som har överlämnats till den.
    • #pragma warn -rch: Det här direktivet döljer de varningar som visas när en kod inte går att nå. Till exempel: all kod som skrivs efter return-angivelsen i en funktion är oåtkomlig.

Denna artikel har bidragits av Harsh Agarwal. Om du gillar GeeksforGeeks och vill bidra kan du också skriva en artikel via contribute.geeksforgeeks.org eller maila din artikel till [email protected]. Se din artikel dyka upp på GeeksforGeeks huvudsida och hjälp andra Geeks.

Lämna ett svar

Din e-postadress kommer inte publiceras.