ESIKÄSITTELYSÄÄNNÖT

C-kääntäjälle voidaan sisällyttää erilaisia ohjeita ohjelman lähdekoodiin. Ohjeet, jotka käsitellään ennen koodin kääntämistä, ovat nimeltään esikäsittelysääntöjä. Kaikki esikäsittelysäännöt alkavat risuaita-merkillä #.

Esikäsittelysäännöt tulkitaan ennen kääntämisprosessin alkamista. Ne kirjoitetaan yleensä ohjelmakoodin alkuun.


TIEDOSTON SISÄLLYTTÄMINEN

Yleisimpiä C-kielessä käytettyjä esikäsittelysääntöjä on tiedoston sisällyttäminen ohjelmaan. Kun tiedosto otetaan ohjelman osaksi, kyseisen tiedoston sisältö asetetaan lähdekoodissa kyseisen komennon kohdalle. Ohjelman jakamista useaan osaan käytetään, kun
• ohjelmakoodi kasvaa suureksi
• samaa ohjelmakoodia käytetään useassa eri ohjelmassa

Ohjelman jakamisen hyöty tulee esille ohjelmakehityksessä kääntämisvaiheessa. Ohjelman osista tarvitsee kääntää vain ne tiedostot, joihin on tehty muutoksia. Suorituskelpoinen binääritiedosto saadaan sitten linkittämällä erillään käännetyt osat.

Tiedoston sisällyttäminen:

#include <tiedostonimi>

Sääntö #include neuvoo kääntäjää sisällyttämään toisen lähdetiedoston siihen koodiin, jossa sääntö sijaitsee. Sisällytettävä tiedosto sijaitsee oletushakemistossa.

Tiedoston sisällyttämisen toinen muoto on:

#include ”tiedostonimi”

Kun tiedosto on lainausmerkeissä kääntäjä etsii tiedostoa nykyisestä hakemistosta. Tätä käytetään käyttäjän itse tekemien tiedostonosion kopiointiin.


MAKROJEN MÄÄRITTELY

Makrojen määrittely liittyy yleisimmin tekstinkäsittely- ja taulukkolaskentaohjelmiin mutta C ohjelmointikielessä on oma makrotoiminto-ominaisuus. Makroja voidaan käyttää mm. vakioiden määrittelyssä. Makrot ovat osa C-esikäsittelijää ja ne prosessoidaan ennen kuin C-kääntäjä kääntää koodin. Kun esikäsittelijä kohtaa makron, makron nimi korvataan pätkällä koodia, joka suorittaa toiminnon. Makroja voidaan käyttää sekä argumenttien kanssa että ilman argumentteja. Makrot toimivat samalla tavalla kuin funktiot mutta eivät ole yhtä monipuolisia.

Makron määrittely

#define tunniste merkkijono

Kun esikäsittelijä kohtaa makron nimen se korvaa nimen merkkijonolla. Tässä kaikki esiintymät tunniste korvataan tekstillä merkkijono.

#define VIISI 5 int main() { printf(”Numero on %d”, VIISI); return 0; }

Esim.

#define AREA length * width #define MESSAGE printf("Tämä on viesti")

Makrojen luontia koskevat säännöt:
• Makron nimen tulee olla niiden sääntöjen mukainen, jotka ovat voimassa C:n kaikille tunnisteille. Makron nimi ei saa sisältää välilyöntejä.
• Makron määrittely ei pääty puolipisteeseen, ellei puolupistettä haluta laittaa korvaavaan merkkijonoon.
• Makroja ei voi käyttää lainausmerkkien sisällä olevina.
• Makrojen määrittelyt on tavallisesti rajattu yhteen riviin.

Esim.

#include <stdio.h> #define ALA pituus * korkeus int main() { int pituus, korkeus; scanf("%d %d", &pituus, &korkeus); printf("%d", ALA); getch(); return 0; }




(Ohjelma ei kysy mitään, anna kaksi kokonaislukua)


Esim. ( ohjelma (alla) ei toimi Dev C++ kääntäjällä)

#include <stdio.h> #define loop for(lines = 1; lines <= n; lines++) { for (count=1; count<=n-lines; count++){ putchar(' ');} for (count=1; count <= 2*lines-1; count++){ putchar('#');} printf("\n"); } int main() { int count, lines, n; scanf("%d2", &n); printf("\n"); loop; return 0; }




MAKROJEN PARAMETRIT

Makroille voidaan välittää myös parametreja, joita voidaan käyttää makron sisällä. Kun makroon välitetään parametri on parametrien nimet lueteltava makron määrittelyssä.

Esim.

#define DISPLAY(i) printf(”%d\n”,i) … DISPLAY(3);

Välitettäessä parametri i makrolle esikäsittelijä kopioi parametrin i tiettyyn paikkaan makron sisällä.


MAKROJEN POISMÄÄRITTELY

Makrot poismääritellään käyttämällä sääntöä #undef. Esikäsittelysääntö poistaa kaikki aikaisemmat makron määrittelyt. Poismäärittelyn jälkeen on mahdollista määritellä makro uudelleen.

#define MAXIM 1024 ....... #undef MAXIM ....... #define MAXIM 512

Makrojen uudelleenkäyttö on käyttökelpoinen suurissa projekteissa ja tilanteissa joissa makroja on muutettava.


EHDOLLINEN KÄÄNTÄMINEN

Ehdollisen kääntämisen yleisidea on, että koodiin sisällytetään esikäsittelysääntöjä. Näiden säännöt tarkistavat tiettyjä määrittelyjä. Mikäli määrittelyt on tehty, kääntäjä kääntää koodin kyseisen määrittelyn kohdalta ehdollisen komennon loppuun. Mikäli ehto on epätosi, kääntäjä korvaa sen tyhjillä riveillä. Ilmaisun testaamiseen käytetään komentoa #if ja komennolla #endif päätetään koodilohko, joka käännetään ehdollisena.

Yleinen muoto:

#if ilmaisu C-komentoja #endif

Jos ilmaisu on tosi kääntäjä kääntää koodilohkon. Muutoin kääntäjä hyppää koodin yli.

Esim.

#define MAX 200 #include <stdio.h> int main() { #if MAX > 100 printf( ”Käännetään yli sataa suuremmat\n” ); #endif getch(); return 0; }




Koska ilmaisu arvioidaan kääntämisen aikana täytyy ilmaisussa käyttää aiemmin määriteltyjä vakio tunnisteita. Ilmaisussa ei voi olla ohjelman muuttujia. Esikäsittelijässä on mahdollista käyttää myös #else -lausetta.

Esim.

#define MAX 50 #include <stdio.h> int main() { #if MAX > 100 printf( ”Yli sata\n” ); #else printf( ”Alle sata\n” ); #endif getch(); return 0; }




Kolmas ehdollisen kääntämisen komento on #elif, joka mahdollistaa sisäkkäisten ehtolauseiden käyttämisen.

#if ilmaus1 komento; #elif ilmaus2 komento; #elif ilmaus3 komento ... #endif

Mikäli ilmaus ei ole tosi, koodia ei käännetä. Tämä mahdollistaa luomaan ohjelmasta useita eri versioita, joista kullakin on eri ominaisuuksia. Esimerkiksi määritellään eri tietokoneille eri otsikkotiedostot ja tämän jälkeen hyödynnetään ehdollisen kääntämisen piirteitä vain tiettyjen ohjelman osien kääntämiseen.