next up previous contents
Elõre: Függvények definíciója és deklarációja Fel: Tárolási osztályokhatáskörök Vissza: Változók élettartama és hatásköre

Egyszerû adatdeklarátorok

Az adatdefiníciók legegyszerûbb formája a következõ:

   tárolási osztály spec.  típus spec.  azonosítólista;

Ha a tárolási osztályt nem specifikáljuk, akkor a következõ két eset lehetséges: ha minden blokkon kívül vagyunk, akkor a változó globális lesz, míg ha valamely blokk belsejében vagyunk, akkor a legbelsõ befoglaló blokkra nézve lokális, dinamikus változó jön létre (tehát auto, ezért ezt a kulcsszót nem is szokás sehol kiírni). Amennyiben a definícióból a típusmegadás hiányzik, akkor azt a fordító int-nek tételezi fel, ez akkor is igaz, ha típusmódosító kulcsszó (short, long, unsigned) mellett nem áll alaptípus. A pelda.c-ben a "register c;" definíció tehát egy elõjeles értelmezésû, gépi szóhosszúságú egésznek foglal le helyet, amelyet dinamikus kezeléssel blokkra lokálisnak vettünk fel, és egyben kértük a fordítót, hogy igyekezzék optimális tárolást használni. (Ha valaki áttanulmányozza a lefordított kódot, láthatja, hogy valóban gépi regiszterbe is kerül.) Néhány további definíció:

           long alfa;
           static unsigned short beta, gamma;
           double x;
           signed char c;
           unsigned char byte;
           unsigned delta;
Ezek közül az elsõ alfa-t hosszú elõjeles egésznek definiálja (az int szokás szerint elmarad), és blokkon kívül globális hatáskörrel, blokkon belül auto-ként veszi fel. A beta és gamma egyaránt elõjel nélküli rövid egész, statikus helyfoglalással; a definíció elhelyezése szerint modulra, vagy blokkra lokális láthatósággal. Az x duplapontosságú valós változó, c és byte karakteresek; elõjeles, illetve elõjel nélküli értelmezéssel, míg delta elõjel nélküli gépi szóhosszúságú egész. Ez utóbbi négy változó vagy globális, vagy auto, attól függõen, hogy definícióik blokkon kívül, vagy belül vannak. Statikus helyfoglalású változó definíciójában elõírhatunk kezdõértéket is úgy, hogy a definiált azonosító után egyenlõségjellel elválasztva kerül az inicializáló kifejezés, például:
           static char c = EOS;
Ennek hatására az adott változót a fordító eleve úgy helyezi el, hogy benne van a megfelelõ kezdõérték, tehát ez az értékadás futási idõben nem igényel idõt. Ehhez azonban természetesen az szükséges, hogy az inicializáló kifejezés ún. állandó kifejezés legyen, azaz fordítási idõben kiértékelhetõ (nem függhet más változók értékétõl). A C nyelv garantálja, hogyha egy statikus helyfoglalású változónak nem adunk kezdõértéket, akkor az csupa 0 bittel lesz inicializálva (azaz a fenti példában felesleges a kezdõérték megadása; ugyanakkor felhívja a figyelmet arra, hogy ki fogjuk ezt használni, és ha netán az EOS értékét megváltoztatnánk, akkor sem fogunk csalódni). Dinamikus változók definíciója után is lehet kezdõértéket írni, azonban ez csupán rövidítés, mert a helyfoglalás után a "kezdõérték" ugyanolyan módon kerül a változóba, mintha értékadó utasítást használnánk. Emiatt az itt használt kifejezésre nincs semmilyen megkötés, még függvényhívásokat is tartalmazhat.

Az elõbbiektõl kissé eltérõ formájú a felsorolt (enum) típusú változók deklarálása. Az általános alak:

tárolási osztály spec. enum  típuscímke { elemlista} azonosítólista;

A - nem kötelezõen megadott - típuscímke az adott felsorolt típus megnevezése lesz, ezt követõen már használható az alábbi forma:

tárolási osztály spec. enum  típuscímke   azonosítólista;

Az elemlista az adott típusba tartozó elemeket adja meg, az azonosítólista a definiált változókat nevezi meg, ha elmarad, akkor csak a típust deklaráljuk késõbbi definíciók kedvéért. Példa felsorolt típusú változók megadására:

       static enum nap {
                         hetfo, kedd, szerda, csutortok,
                         pentek, szombat, vasarnap
                       } ma;
       enum nap tegnap, holnap;
Az Olvasó talán észrevette, hogy az extern kulcsszót eddig nem használtuk. Nos, ez azért van, mert a globális változók definíciójánál nem is szabad kiírni. Ezzel a kulcsszóval azt jelezzük, hogy nem definiáljuk az adott változót, hanem deklaráljuk. A globális változókat más modulokban is használhatjuk, de ahhoz, hogy a fordítóprogram az azonosítót megfelelõen értelmezhesse, azt számára deklarálni kell. Az extern kulcsszó szerepe tehát jelezni azt, hogy az azt követõ deklaráció valami olyan tárolási egységre vonatkozik, amelyet egy másik - az aktuális modulra nézve külsõ - modulban definiáltunk.

Általános szabály, hogy csak olyan változót szabad a C-ben használni, amelyik az adott modulban - akár include file-okon keresztül - elõzõleg deklarálva van. Egy modulra nézve külsõ globális változók deklarációja formailag megegyezik definíciójukkal, a tárolási osztályuk extern, és természetesen nem szerepelhet kezdõértékadás. Például:

       extern short unsigned kulso_valtozo;
Egydimenziós tömbváltozó (array) megadása a név után [ ]-be írt elemszámmal (felsõ indexhatár + 1) történik, például a
       float vektor[20];
sor egy 20 lebegõpontos elembõl álló vektor nevû tömböt definiál. Hivatkozni az egyes tömbelemekre tetszõleges kifejezéssel lehet. A tömbindexek a C nyelvben mindig 0-tól indulnak, és a megadott méretnél eggyel kisebb értékig mehetnek, tehát példánknál vektor[0]-tól vektor[19]-ig. Statikus tömbök inicializálhatók is, { }-ek közé zárt elemlistával, például:
       static short paratlan[ ] = {
                                    1,  3,  5,  7,  9, 
                                   11, 13, 15, 17, 19
                                  };
Figyeljük meg, hogy ebben az esetben az indexméret el is maradhat, mert a fordítóprogram a kezdõértékek száma alapján foglalja le a szükséges tárterületet. Karaktertömbök sztringek segítségével is inicializálhatók:
       static char hiba[ ] = "Hibas nev!";
Itt a hiba tömb 11 elemû lesz, hiba[10] értéke EOS lesz. Ha egy sztring nem kezdõértékként jelenik meg a programban, akkor az egy statikus helyfoglalású, az adott karakterekkel (+ az EOS) inicializált tárterület foglaló egység lesz, azonosító nélkül.

Mutatók definiálását (vagy deklarálását, ez ebbõl a szempontból közömbös) a mutatott típus definíciójából vezethetjük le. Ha

       unsigned short abc;
definiálja az abc-t, mint egy rövid, elõjel nélküli egész változót, akkor
       unsigned short *bcd;
definiálja a bcd-t, mint egy rövid, elõjel nélküli egészre mutató pointert. Hasonlóan register char *p; definiálja p-t, mint egy (elõjeles) karakterre mutató pointert. A p mutató dinamikus helyfoglalással kerül tárolásra, blokkra lokális és lehetõség szerint regiszterben lesz elhelyezve (ez utóbbi a BORLAND C++-ban függ a memóriamodelltõl is). Hasonló elven tetszõleges alaptípusra mutató pointer definiálható. A tömbökre és a mutatókra késõbb még részletesebben visszatérünk a 1.9-es alfejezetben.


next up previous contents
Elõre: Függvények definíciója és deklarációja Fel: Tárolási osztályokhatáskörök Vissza: Változók élettartama és hatásköre