logo

C Esiprosessorit

Esiprosessorit ovat ohjelmia, jotka käsittelevät lähdekoodin ennen varsinaisen kääntämisen alkamista. Ne eivät ole osa käännösprosessia, mutta ne toimivat erikseen, jolloin ohjelmoijat voivat muokata koodia ennen kääntämistä.

  • Se on ensimmäinen vaihe, jonka C-lähdekoodi käy läpi, kun se muunnetaan suoritettavaksi tiedostoksi.
  • Esikäsittelydirektiivien päätyypit ovat  Makrot Tiedoston sisällyttämisen ehdollinen käännös ja muut käskyt, kuten #undef #pragma jne.
  • Pääasiassa näitä direktiivejä käytetään korvaamaan tietty C-koodin osa toisella C-koodilla. Jos esimerkiksi kirjoitamme '#define PI 3.14', esiprosessori korvaa PI:n 3.14:llä.
C Esiprosessorit

C-esiprosessorien tyypit

Kaikki edellä mainitut esiprosessorit voidaan luokitella 4 tyyppiin:

Makrot

Makrot käytetään määrittämään vakioita tai luomaan funktioita, jotka esikäsittelijä korvaa ennen koodin kääntämistä. Kaksi esiprosessoria #määritellä ja #undef käytetään makrojen luomiseen ja poistamiseen C:ssä.



#määritellä tokenin arvo
#undef merkki

missä esikäsittelyn jälkeen merkki laajennetaan siihen arvo ohjelmassa.

Esimerkki:

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

Lähtö
0 1 2 3 4 

Yllä olevassa ohjelmassa ennen kääntämisen alkamista sana LIMIT korvataan 5:llä. Sana 'RAJOITTAA' makron määritelmässä kutsutaan makromalliksi ja "5" on makrolaajennus.

Huom Makromääritelmän lopussa ei ole puolipistettä (;). Makromääritelmät eivät tarvitse puolipistettä loppuakseen.

On myös joitain Ennalta määritetyt makrot C:ssä jotka ovat hyödyllisiä tarjoamalla ohjelmallemme erilaisia ​​toimintoja.

Aiemmin määritetty makro voidaan määrittää määrittelemättömäksi käyttämällä #undef esikäsittelyohjelmaa. Esimerkiksi yllä olevassa koodissa

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; } 


Lähtö:

./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

Makrot argumenteilla

Voimme myös välittää argumentteja makroille. Nämä makrot toimivat samalla tavalla kuin funktiot. Esimerkiksi

# määritellä foo(a b) a + b
#define func(r) r * r

Ymmärrämme tämän ohjelman avulla:

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; } 

Lähtö
Area of rectangle is: 50 

Selitys: Yllä olevassa ohjelmassa makro ALUE(l b) on määritetty laskemaan suorakulmion pinta-ala kertomalla sen pinta-ala pituus (l) ja leveys (b) . Kun ALUE(a b) kutsutaan sitä laajenee (a * b) ja tulos lasketaan ja tulostetaan.

Katso Makrotyypit C:ssä lisää esimerkkejä ja tyyppejä.

localdatetime java

Tiedoston sisällyttäminen

Tiedostojen sisällyttäminen mahdollistaa ulkoisten tiedostojen (otsikkotiedostokirjastojen jne.) sisällyttämisen nykyiseen ohjelmaan. Tämä tehdään yleensä käyttämällä #sisällytä direktiivi, joka voi sisältää sekä järjestelmän että käyttäjän määrittämiä tiedostoja.

Syntaksi

On kaksi tapaa sisällyttää otsikkotiedostoja.

#sisältää
#sisältää 'tiedostonimi'

The '<' ja '>' suluissa käske kääntäjää etsimään tiedosto tiedostosta vakiohakemisto samalla kun lainausmerkit ( ' ' ) käske kääntäjää etsimään otsikkotiedostoa lähdetiedoston hakemistosta.

Esimerkki:

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

Lähtö
Hello World

Ehdollinen kokoelma

Ehdollinen kokoelma voit sisällyttää tai jättää pois koodin osia tietyistä ehdoista riippuen. Tämä on hyödyllinen alustakohtaisen koodin luomisessa tai virheenkorjauksessa. On olemassa seuraavat ehdolliset esikäsittelykäskyt: #if #ifdef #ifndef else #elif ja #endif

Syntaksi

Ehdollisten esiprosessorien yleinen syntaksi on:

#jos
// joku koodi
#elif
// lisää koodia
#muu
// Lisää koodia
#endif

#endif-käskyä käytetään sulkemaan #if #ifdef- ja #ifndef-avauskäskyt.

Esimerkki

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; } 

Lähtö
PI is defined Square is not defined

Selitys: Tämä koodi käyttää ehdollisia esikäsittelyohjeita ( #ifdef #elif ja #ifndef ) tarkistaaksesi, ovatko tietyt makrot ( PI ja NELIÖ ) on määritelty. Koska PI on määritelty, ohjelma tulostaa PI on määritelty ' tarkistaa sitten, ettei NELIÖ ole määritetty ja tulostaa Neliötä ei ole määritelty '.

Muut direktiivit

Ensisijaisten esikäsittelyohjeiden lisäksi C tarjoaa myös muita direktiivejä kääntäjien käyttäytymisen ja virheenkorjauksen hallintaan.

#pragma:

Antaa kääntäjälle erityiset ohjeet sen käyttäytymisen hallitsemiseksi. Sitä käytetään poistamaan käytöstä varoitusasetusten kohdistus jne.

Syntaksi

#pragma direktiivi

Joitakin #pragma-direktiivejä käsitellään alla: 

  1. #pragma startup: Nämä käskyt auttavat meitä määrittämään funktiot, jotka on suoritettava ennen ohjelman käynnistystä (ennen kuin ohjaus siirtyy main()-funktioon).
  2. #pragma poistu : Nämä käskyt auttavat meitä määrittämään funktiot, jotka on suoritettava juuri ennen ohjelman lopettamista (juuri ennen kuin ohjaus palaa main()-funktiosta).

Esimerkki

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; } 

Lähtö
Inside main() 

Yllä oleva koodi tuottaa yllä olevan tulosteen, kun se ajetaan GCC-kääntäjillä, kun odotettu tulos oli:

Odotettu tulos

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

Tämä johtuu siitä, että GCC ei tue #pragma käynnistystä tai lopettamista. Voit kuitenkin käyttää alla olevaa koodia odotettuun tulokseen GCC-kääntäjissä. 

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; } 

Lähtö
Inside func1() Inside main() Inside func2() 

Yllä olevassa ohjelmassa olemme käyttäneet joitain tietyt syntaksit niin, että yksi funktioista suoritetaan ennen päätoimintoa ja toinen pääfunktion jälkeen.

Luo tietokilpailu