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-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 inMakrot 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:
- #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).
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