CPP (antaŭtraktilo)

El Vikipedio, la libera enciklopedio
Jump to navigation Jump to search

CPP, mallongigo de la angla the C PreProcessor, t.e. Antaŭtraktilo por C estas komputila programo kiu plenumas la antaŭtraktadon de tradukotaj programoj prezentitaj en C aŭ en C++. Ĝi estas enkonstruita en la tradukilojn de tiuj programlingvoj, sed estas antaŭ disponebla kiel aparta utilaĵo cpp.

Plimulto da esprimiloj de CPP havas la formon de direktivoj (escepto estas la makrokomandoj). Ĉiu direktivo okupas apartan linion en la fonta teksto, kaj estas markita per antaŭmetita kradsigno #.

En sia rolo de antaŭtraktilo CPP realigas la sekvajn taskojn:

  • ĝi importas ĉapdosierojn per la direktivo #include
  • ĝi plenumas la makrotraktadon;
  • ĝi forigas nedeziratajn partojn de la fonta programo ĉe kondiĉa traduko.

Inkludo[redakti | redakti fonton]

La inkludo-direktivo estas la plej ofte uzata en la C-programoj; en ĉi-suba programo la direktivo #include <stdio.h> anstataŭiĝos per la enhavo de la dosiero stdio.h:

#include <stdio.h>
int main(void)
{
    printf("Saluton, mondo!\n");
    return 0;
}

La kondiĉa traduko[redakti | redakti fonton]

Ĝin regas la direktivoj #if, #ifdef, #ifndef, #else, #elif and #endif. Ekz-e oni povas ordoni al la tradukilo programi erarserĉan printadon nur tiam, kiam oni kreas tre babileman version:

#if BABILEMO >= 2
  print("Hello world!");
#endif

Makrooj[redakti | redakti fonton]

La direktivo #define servas por enkonduki makrodifinojn. Tiuj povas esti tre simplaj mallongigoj, ekz-e

#define pi 3.1415926536

aŭ parametrohava teksto, ekz-e

#define MAX(a,b) (a)>(b)?(a):(b)

Kun ĉi tiuj difinoj CPP transformos la fontotekstan ordonon

x = MAX(x, z + pi/2);

ĉi tiel:

x = (x)>(z + 3.1415926536/2)?(x):(z + 3.1415926536/2);

   Esperantigo de la ŝlosilvortoj de C[redakti | redakti fonton]

Ĉi-suba ekzemplo, pruntita el la Komputada Leksikono, demonstras uzon de CPP por esperantigi la ŝlosilvortojn de C. Interalie, ĝi ankaŭ klarigas la signifon de la anglaj ŝlosilvortoj.

Estu jena ĉapdosieo eoc.h:

#define AUXTO        auto 
#define ELIRU        break 
#define OKAZO        case 
#define SIGNA        char 
#define SIGNAJ       char 
#define KOMPLEKSA    complex 
#define KOMPLEKSAJ   complex 
#define KONST        const 
#define PLU          continue 
#define CETERE       default 
#define FARU         do 
#define DUOBLA       double 
#define DUOBLAJ      double 
#define ALIE         else 
#define ENUM         enum 
#define EKSTERA      extern 
#define EKSTERAJ     extern 
#define REELA        float 
#define REELAJ       float 
#define POR          for 
#define AL           goto 
#define SE           if 
#define IMAGINARA    imaginary 
#define MALFERMITA   inline 
#define ENTJERA      int 
#define ENTJERAJ     int 
#define LONGA        long 
#define LONGAJ       long 
#define REGXISTRO    register 
#define REGXISTROJ   register 
#define EKSKLUZIVA   restrict 
#define EKSKLUZIVAJ  restrict 
#define REEN         return 
#define KURTA        short 
#define KURTAJ       short 
#define SIGNUMA      signed 
#define SIGNUMAJ     signed 
#define DABAJTOJ     sizeof 
#define STATIKA      static 
#define STATIKAJ     static 
#define RIKORDO      struct 
#define STRUKTURO    struct 
#define ELEKTU       switch 
#define TIPDIFINO    typedef 
#define UNIO         union 
#define NATURA       unsigned 
#define NATURAJ      unsigned 
#define VAKA         void 
#define VARIEMA      volatile 
#define VARIEMAJ     volatile 
#define DUM          while

La programoj uzantaj ĉi tiun dosieron devas ĝin importi, ekz-e kiel en la sekva deklaro de funkcio cxen_al_ent, konvertanta signoĉenojn kiuj prezentas nombrojn (ekz-e "+127") en enjerojn (samkiel la konata C-funkcio atoi):

#include "eoc.h"
ENTJERA cxen_al_ent(SIGNA *cx) 
{ 
    ENTJERAJ i, n, minuso = 0;    /* lokaj variabloj */ 
    POR(i = 0; cx[i] == ' ' || cx[i] == '\n' || cx[i] == '\t'; i++) ; 
     ELEKTU(cx[i]) { 
        OKAZO '-': minuso = 1; 
        OKAZO '+': i++; 
     } 
     POR(n = 0; cx[i] >= '0' && cx[i] <= '9';) 
        n = 10 * n + cx[i++] - '0'; 
     REEN minuso ? -n : n ; 
}

Metinte ĉi tiun programon en dosieron al_ent.c, oni povas rekte ĝin traduki per gcc (kaj ricevi celkodan dosieron al_ent.o), aŭ aparte trakti per cpp, kaj ricevi programon en la norma C:

$ gcc -c al_ent.c && ls -s *.o
4 al_ent.o
$
$ cpp -P al_ent.c 
int cxen_al_ent(char *cx)
{
    int i, n, minuso = 0;
    for(i = 0; cx[i] == ' ' || cx[i] == '\n' || cx[i] == '\t'; i++) ;
    switch(cx[i]) {
        case '-': minuso = 1;
        case '+': i++;
    }
    for(n = 0; cx[i] >= '0' && cx[i] <= '9';)
        n = 10 * n + cx[i++] - '0';
    return minuso ? -n : n ;
}
$