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-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 * rYmmä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: 50Selitys: 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ä.
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 #includeint main () { printf ( 'Hello World' ); return 0 ; }
LähtöHello WorldEhdollinen 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 defined n ' ); // If PI is not defined check if SQUARE is defined #elif defined(SQUARE) printf ( 'Square is defined n ' ); // 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 definedSelitys: 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#includevoid 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#includevoid 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