Esiprosessorit ovat ohjelmia, jotka käsittelevät lähdekoodin ennen kääntämistä. Ohjelman kirjoittamisen ja ohjelman suorittamisen välillä on useita vaiheita C-kielellä. Katsotaanpa näitä vaiheita ennen kuin alamme oppia esikäsittelijöistä.

Näet välivaiheet yllä olevasta kaaviosta. Ohjelmoijien kirjoittama lähdekoodi tallennetaan ensin tiedostoon, olkoon nimi ohjelma.c . Esiprosessorit käsittelevät tämän tiedoston ja luodaan laajennettu lähdekooditiedosto nimeltä program.i. Kääntäjä kääntää tämän laajennetun tiedoston ja luodaan objektikooditiedosto nimeltä program.obj. Lopuksi linkittäjä linkittää tämän objektikooditiedoston kirjastotoimintojen objektikoodiin suoritettavan tiedoston program.exe luomiseksi.
Esikäsittelydirektiivit julkaisussa C
Esiprosessoriohjelmat tarjoavat esikäsittelyohjeita, jotka käskevät kääntäjää esikäsittelemään lähdekoodin ennen kääntämistä. Kaikki nämä esikäsittelijän käskyt alkavat '#' (hash) -symbolilla. #-symboli osoittaa, että mikä tahansa lause, joka alkaa #-merkillä, menee esikäsittelyohjelmaan suoritettavaksi. Voimme sijoittaa nämä esikäsittelijän käskyt minne tahansa ohjelmassamme.
Esimerkkejä esikäsittelyohjeista ovat: #sisältää , #määritellä , #ifndef, jne.
Huomautus Muista, että # symboli tarjoaa vain polun esiprosessoriin, ja esiprosessoriohjelma käsittelee komennon, kuten include. Esimerkiksi #include sisältää ohjelmassasi määritetyn tiedoston koodin tai sisällön.
Luettelo C:n esikäsittelyohjeista
Seuraavassa taulukossa luetellaan kaikki C:n esiprosessorin käskyt:
| Esikäsittelijädirektiivit | Kuvaus |
|---|---|
| #määritellä | Käytetään makron määrittämiseen |
| #undef | Käytetään makron määrityksen poistamiseen |
| #sisältää | Käytetään sisällyttämään tiedosto lähdekoodiohjelmaan |
| #ifdef | Käytetään sisällyttämään koodin osio, jos tietty makro on määritetty #define:lla |
| #ifndef | Käytetään sisällyttämään koodiosio, jos tiettyä makroa ei ole määritetty #define-parametrilla |
| #jos | Tarkista määritetty kunto |
| #muu | Vaihtoehtoinen koodi, joka suoritetaan, kun #if epäonnistuu |
| #loppu Jos | Käytetään merkitsemään #if, #ifdef ja #ifndef loppu |
Nämä esiprosessorit voidaan luokitella niiden suorittaman toiminnon tyypin perusteella.
C-esiprosessorien tyypit
Esikäsittelijädirektiivejä on 4 päätyyppiä:
- Makrot
- Tiedoston sisällyttäminen
- Ehdollinen kokoelma
- Muut direktiivit
Opitaan nyt jokaisesta näistä direktiiveistä yksityiskohtaisesti.
1. Makrot
C:ssä makrot ovat ohjelman koodinpätkiä, joille on annettu jokin nimi. Aina kun kääntäjä kohtaa tämän nimen, kääntäjä korvaa nimen todellisella koodinpalalla. The '#määritellä' -direktiiviä käytetään makron määrittelemiseen.
Makromääritelmän syntaksi
#define token value>
jossa esikäsittelyn jälkeen merkki laajennetaan siihen arvo ohjelmassa.
Esimerkki makrosta
C
// C Program to illustrate the macro> #include> // macro definition> #define LIMIT 5> int> main()> {> >for> (>int> i = 0; i printf('%d
', i); } return 0; }> |
>
>Lähtö
0 1 2 3 4>
Yllä olevassa ohjelmassa, kun kääntäjä suorittaa sanan LIMIT, se korvaa sen 5:llä. 'RAJA' makron määritelmässä kutsutaan makromalliksi ja '5' on makrolaajennus.
Huomautus 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.
Makrot argumenteilla
Voimme myös välittää argumentteja makroille. Argumenteilla määritellyt makrot toimivat samalla tavalla kuin funktiot.
Esimerkki
#define foo( a, b ) a + b #define func(r) r * r>
Ymmärrämme tämän ohjelman avulla:
C
// C Program to illustrate function like macros> #include> // macro with parameter> #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;> }> |
>
>Lähtö
Area of rectangle is: 50>
Yllä olevasta ohjelmasta voidaan nähdä, että aina kun kääntäjä löytää ohjelmasta AREA(l, b), se korvaa sen lauseella (l*b). Ei vain tämä, vaan myös makromalliin AREA(l, b) välitetyt arvot korvataan käskyssä (l*b). Siksi AREA(10, 5) on yhtä suuri kuin 10*5.
2. Tiedoston sisällyttäminen
Tämän tyyppinen esiprosessoridirektiivi käskee kääntäjää sisällyttämään tiedoston lähdekoodiohjelmaan. The #include esikäsittelyohje käytetään sisällyttämään otsikkotiedostot C-ohjelmaan.
Käyttäjä voi sisällyttää ohjelmaan kahdenlaisia tiedostoja:
Vakiootsikkotiedostot
Vakiootsikkotiedostot sisältävät määritelmiä esim. määritellyistä toiminnoista printf(), scanf(), jne. Nämä tiedostot on sisällytettävä toimiin näiden toimintojen kanssa. Eri funktiot on ilmoitettu eri otsikkotiedostoissa.
Esimerkiksi tavalliset I/O-toiminnot ovat 'iostream'-tiedostossa, kun taas funktiot, jotka suorittavat merkkijonotoimintoja, ovat 'merkkijono'-tiedostossa.
Syntaksi
#include < file_name>>>missä Tiedoston nimi on sisällytettävän otsikkotiedoston nimi. The ’’ suluissa käske kääntäjää etsimään tiedostoa s:stä tavallinen hakemisto.
Käyttäjän määrittämät otsikkotiedostot
Kun ohjelma kasvaa erittäin suureksi, on hyvä käytäntö jakaa se pienempiin tiedostoihin ja sisällyttää ne tarvittaessa. Tämäntyyppiset tiedostot ovat käyttäjän määrittämiä otsikkotiedostoja.
Syntaksi
The lainausmerkit ( ) käske kääntäjää etsimään otsikkotiedostoa lähdetiedoston hakemistoon.
3. Ehdollinen kokoaminen
Ehdollinen käännös C-direktiiveissä on eräänlainen direktiivi, joka auttaa kääntämään tietyn osan ohjelmasta tai ohittamaan ohjelman tietyn osan kääntämisen joidenkin ehtojen perusteella. Ehdollisen koodin lisäämiseen käytetään seuraavia esikäsittelyohjeita:
- #if-direktiivi
- #ifdef direktiivi
- #ifndef-direktiivi
- #else direktiivi
- #elif-direktiivi
- #endif-direktiivi
#loppu Jos -direktiiviä käytetään sulkemaan #if-, #ifdef- ja #ifndef-avauskäskyt, mikä tarkoittaa, että näiden ohjeiden esikäsittely on valmis.
Syntaksi
#ifdef macro_name // Code to be executed if macro_name is defined # ifndef macro_name // Code to be executed if macro_name is not defined #if constant_expr // Code to be executed if constant_expression is true #elif another_constant_expr // Code to be excuted if another_constant_expression is true #else // Code to be excuted if none of the above conditions are true #endif>
Jos makro, jonka nimi on ' makron_nimi ' on määritelty, lausekelohko suoritetaan normaalisti, mutta jos sitä ei ole määritelty, kääntäjä yksinkertaisesti ohittaa tämän lausekelohkon.
Esimerkki
Alla oleva esimerkki osoittaa esikäsittelyohjeiden #include #if, #elif, #else ja #endif käytön.
C
//program to demonstrates the use of #if, #elif, #else,> // and #endif preprocessor directives.> #include> // defining PI> #define PI 3.14159> int> main()> {> > #ifdef PI> >printf>(>'PI is defined
'>);> > #elif defined(SQUARE)> >printf>(>'Square is defined
'>);> #else> >#error 'Neither PI nor SQUARE is defined'> #endif> > #ifndef SQUARE> >printf>(>'Square is not defined'>);> #else> >cout <<>'Square is defined'> << endl;> #endif> >return> 0;> }> |
localdatetime java
>
>Lähtö
PI is defined Square is not defined>
4. Muut direktiivit
Edellä mainittujen direktiivien lisäksi on olemassa kaksi muuta direktiiviä, joita ei käytetä yleisesti. Nämä ovat:
- #undef direktiivi
- #pragmadirektiivi
1. #undef-direktiivi
#undef-direktiiviä käytetään olemassa olevan makron määrittelyn poistamiseen. Tämä direktiivi toimii seuraavasti:
#undef LIMIT>
Tämän lausekkeen käyttäminen poistaa nykyisen makron LIMIT. Tämän lausunnon jälkeen jokainen #ifdef LIMIT -lause tulee epätosi.
Esimerkki
Alla oleva esimerkki havainnollistaa #undef-direktiivin toimintaa.
C
#include> // defining MIN_VALUE> #define MIN_VALUE 10> int> main() {> >// Undefining and redefining MIN_VALUE> printf>(>'Min value is: %d
'>,MIN_VALUE);> > //undefining max value> #undef MIN_VALUE> > // again redefining MIN_VALUE> #define MIN_VALUE 20> >printf>(>'Min value after undef and again redefining it: %d
'>, MIN_VALUE);> >return> 0;> }> |
>
>Lähtö
Min value is: 10 Min value after undef and again redefining it: 20>
2. #pragmadirektiivi
Tämä direktiivi on erityiskäyttöön tarkoitettu direktiivi, ja sitä käytetään joidenkin ominaisuuksien kytkemiseen päälle tai pois päältä. Tämäntyyppiset direktiivit ovat kääntäjäkohtaisia, eli ne vaihtelevat kääntäjästä toiseen.
Syntaksi
#pragma directive>
Joitakin #pragma-direktiivejä käsitellään alla:
- #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).
- #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).
Alla oleva ohjelma ei toimi GCC-kääntäjien kanssa.
Esimerkki
Alla oleva ohjelma havainnollistaa #pragma exit ja pragma startup -toimintojen käyttöä
C
// C program to illustrate the #pragma exit and pragma> // startup> #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()
'>); }> void> func2() {>printf>(>'Inside func2()
'>); }> // driver code> int> main()> {> >void> func1();> >void> func2();> >printf>(>'Inside main()
'>);> >return> 0;> }> |
>
>
Odotettu tulos
Inside func1() Inside main() Inside func2()>
Yllä oleva koodi tuottaa alla olevan tulosteen, kun se ajetaan GCC-kääntäjillä:
Inside main()c>
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()
'>);> }> void> func2()> {> >printf>(>'Inside func2()
'>);> }> int> main()> {> >printf>(>'Inside main()
'>);> >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.
#pragma varoitusdirektiivi
Tätä ohjetta käytetään piilottamaan varoitusviesti, joka näytetään kääntämisen aikana. Voimme piilottaa varoitukset alla olevan kuvan mukaisesti:
- #pragma varoittaa -rvl : Tämä direktiivi piilottaa ne varoitukset, jotka tulevat esiin, kun funktio, jonka oletetaan palauttavan arvon, ei palauta arvoa.
- #pragma varoittaa -par : Tämä direktiivi piilottaa ne varoitukset, jotka tulevat esiin, kun funktio ei käytä sille välitettyjä parametreja.
- #pragma varoittaa -rch : Tämä direktiivi piilottaa ne varoitukset, jotka annetaan, kun koodiin ei saada yhteyttä. Esimerkiksi mikä tahansa koodin jälkeen kirjoitettu koodi palata funktiossa oleva lause ei ole tavoitettavissa.
Jos pidät techcodeview.comsta ja haluat osallistua, voit myös kirjoittaa artikkelin käyttämällä . Katso artikkelisi ilmestyvän techcodeview.com-pääsivulle ja auta muita nörtejä. Kirjoita kommentteja, jos huomaat jotain väärin tai jos haluat jakaa lisätietoja yllä käsitellystä aiheesta.