Személyes eszközök
Keresés

 

A InfoWiki wikiből


Példa

A harmadik generációs programozási nyelvek egyik nagy előnye, hogy numerikus kifejezéseket írhatunk. A korábbi generációkban (gépi kód, assembly) egy numerikus kifejezés kiértékelését lépésekre kellett bontani. Ezen lépéssorozat elolvasásával deríthető csak ki, hogy mi is az, amit éppen számolunk.

int r = 14;
double a = 2*r*3.14;

A fenti példában az a változóta vonatkozó értékadó utasítás jobb oldalán egy numerikus kifejezés áll, három adattal, és két operátorral. Ismert, hogy egy értékadó utasítás akkor végrehajtható, ha a jobb oldal típusa megegyezik, vagy implicit módon konvertálható a bal oldal típusába.

Írjuk fel ezt az értékadó utasítást tisztán típusokkal:

double = int * int * double;

Határozzuk meg a jobb oldal típusát. Ehhez a kifejezésbeli operátorok végrehajtási sorrendjét kell ismerni. Ez esetben egyszerű a helyzet, mindkét operátorunk a szorzás operátor, ezek balról jobbra sorrendben hajtódnak végre:

Először végrehajtódik az int*int, amelynek eredménye szintén int. Ha az első szorzás után vizsgáljuk a kifejezést, akkor már csak ennyi van ott:

double = int * double;

Itt most gond van, mivel int*double következik.

Korábban volt már utalás arra, hogy nem egyforma típusú adatok közötti műveletvégzés során a háttérben típusegyeztető lépések történnek. Ennek oka, hogy a lebegőpontos ko-processzor csak egyforma adattípusok között tud műveletet végrehajtani, különböző típusok között nem (ennek is oka van persze, bővebben erről a Bevezetés az informatika-ba, illetve a Számítógép-architektúrák tárgyban lehet olvasni).

A típusegyeztetést az előző fejezetben nevén neveztük: implicit típuskonverzió hajtódik végre. Mivel double->int implicit típuskonverzió nincs, de int->double van, ezért a fordítóprogram itt automatikusan alkalmazza azt, és a fenti kifejezés double*double típusok között fog végrehajtódni, mely szorzásnak ez esetben az eredménye is double.

Ezzel meg is kaptuk a fenti kifejezés végeredményének a típusát. Ezt most a fordító összeveti a bal oldal típusával:

double = double;

Mivel a két oldal megegyezik, nem kell további implicit típuskonverziót alkalmazni sem - az értékadó utasítás típushelyes, tehát végrehajtható.

Numerikus kifejezések

A numerikus kifejezések kiértékelésének két szintje van:

  • a konkrét végeredmény-értéktől függetlenül csupán a kifejezésben részt vevő típusok és operátorok ismeretében a kifejezés eredméynének típusa levezethető
  • a kiértékelés során lépésenként egyszerűsítjük a kifejezést, egy lépésben egy operátort végrehajtva mindaddig, amíg a konkrét végerdményt meg nem kapjuk. Ennek során a műveleti prioritásokat és kötési szabályokat kell betartani.

Típuslevezetés

A kifejezés eredményének típusát a fordítóprogram vezeti le. Erre azért van szükség, hogy ezen típust összevethesse pl. az értékadó utasítás bal oldalának típusával, és eldönthesse, hogy kell-e (tud-e) alkalmazni implicit típuskonverzót, illetve az értékadó utasítás típushelyes-e.

A típuslevezetés során minden esetben csak egy konkrét operátor végrehajtását kell vizsgálni. Majd ezt a szabályt alkalmani újra-és-újra, amíg az egyszerűsített kifejezésünk egy elemű nem lesz. Ekkor megkaptuk a kifejezés eredmény-típusát. Tegyük fel, hogy a vizsgált kifejezés-rész A op B alakú (ahol A és B egy-egy típus, az op egy numerikus operátor, pl. összeadás, kivonás, stb).

  • amennyiben A és B megegyezik, úgy az A op B végrehajtásának eredményének típusa is marad A típusú
  • amennyiben A és B nem egyforma, de létezik implicit típuskonverió A->B irányban, akkor ezt a fordító ezen a ponton betervezi a végrehajtás menetébe. Innentől kezdve az op operátort két B típusú érték között kell végrehajtani, vagyis az eredmény típusa B lesz
  • hasonlóan, ha létezik B->A implicit típuskonverzió, akkor az betervezésre kerül, az op két darab A típusú értéken lesz végrehajtva, és az eredmény típusa is A lesz
  • amennyiben A és B nem egyezik meg, és egyiket sem lehet átalakítani implicit módon a másik típusára, akkor a numerikus kifejezésünk típus-helytelen. A fordítóprogram szintaktikai hibát jelez, és a fordítás ezen a ponton megáll.

Az utolsó eset nem jelent végleges problémát. Elképzelhető, hogy létezik explicit típuskonverzió vagy A->B vagy B->A irányban. A szintaktikai hiba esetén a programozó a megfelelő helyre beírhatja ezen explicit típuskonverziót (amennyiben ez nem okoz gondot), és újra próbálkozhat a fordítással.

Ami fontos észrevétel: egy A op B rész-kifejezés típusa vagy A vagy B lesz. Amennyiben A=B, úgy ezen egyforma típus. Amennyiben különbözőek, úgy a nagyobb típus lesz.

A fenti szabályok figyelembevételével, lépésenkét haladva tetszőleges bonyolultásgú kifejezés típusát le lehet vezetni.

Hernyák Zoltán
A lap eredeti címe: „http://wiki.ektf.hu/wiki/Mp1/page160
Nézetek
nincs sb_3.145.183.137 cikk