Személyes eszközök
Keresés

 

A InfoWiki wikiből


Literál

A programok valójában két fontos részből állnak:

  • adatok, amelyekkel a program utasításai műveleteket végez, számol vele
  • utasítások, amelyek a részeredményeket előállítják, ellenőrzik

Az adatok a programba két helyről kerülhetnek be:

  • eleve tartalmazza a program szövege valamely adat értékét, legyen ez a Pi értéke, amely ~3.14, vagy az ÁFA kulcsa, 20%, stb.
  • külső forrásból futás közben kerülhet be, ez a külső forrás lehet billentyűzetről bevitel következménye, adatbázisból olvasás eredménye, stb

Azok az értékek, amelyek a program szövegében eleve benne vannak, két formában létezhetnek:

  • literál
  • konstans

Ezen két forma nagyon sok hasonlóságot mutat egymással, ezért gyakran kérdéses mikor melyiket kell alkalmazni. Ezekkel kapcsolatos tanácsok, útmutatókról majd későb lesz szó.

A literálok

A literál nem más, mint a program szövegében direkt módon beleírt adat. Nézzük az alábbi példát:

2*r*Pi

Ebben a példában a 2 egy literál, a program szövegébe beszúrt számérték.

A literálokról tudni kell, hogy:

  • van értékük (értéket képviselnek)
  • van típusuk

A literál típusa az alakjából van kikövetkeztetve. Ezt a következtetést, típusfelismerést a fordítóprogram végzi. A literál típusa tehát ismert, de a forráskód maga nem tartalmaz erre direktben utalást, jelölést - nincs odaírva a 2 környékére hogy ő int típusú. Amikor a típus nem ismert, de kikövetkeztethető, akkor implicit típusmegadás-ról beszélünk.

A III. generációs programozási nyelvek jellemzője, hogy mindennek van típusa, még annak is, aminek ez nem látszik elsőre egyértelműen. A típusokat vagy implicit módon, vagy explicit módon kell megadni. Az explicit típusmegadás során a programozó eleve leírja az általa választott, kívánt típus nevét (int, double, string, ..). Az implicit megadás során a programozó elég egyértelmű szituációt teremt, hogy a fordítóprogram maga következtethesse ki a típust.


A 2 literál egy tízes számrendszerben megadott int típusú érték.

Egész szám literálok

Amennyiben a program szövegébe egy egész számot írunk be, akkor azt megtehetjük:

  • tízes számrendszerbeli alakban
  • tizenhatos számrendszerbeli alakban

A leggyakoribb a tizes számrendszerbeli alak. A -14, a 25, a 245678 mindegyike egy-egy egész szám literál. De az egész szám egy típuscsalád neve, a típust pedig konkrétan kell választani és megnevezni. Milyen típusa van a 18-nak?

Az a baj, hogy erre sok jelentkező lehetne, mivel a 18 mint érték gyakorlatilag az összes egész típusban leírható, mindegyike szóba jöhetne választásként. A -18 már megfelezné a szóba jöhető típusok számát, mivel csak az előjeles típusok jöhetnek szóba.

A fordítóprogram az egész szám típusoknák megadott szempontok szerint nem mérlegel hosszasan a szóba jöhető típusok között, minden egész szám formájú literált egy kalap alá vesz -> int típust választja nekik.

Minden egész szám literál implicit típusa a fordítóprogram szerint int lesz, vagyis 4 byte-os, előjeles egész (ez akkor is igaz, ha tizenhatos számrendszerben adtuk meg az értéket).


Pazarlónak tűnik ez a nagyvonalúság, mivel a 18 értékhez választható típus a byte is, s ennek a tárolási helyigénye negyede az int-ének. De ha újraolvassuk a processzor memóriaelérési stratégiáját, rájöhetünk hogy az 1 byte-os tárolású adatok sem feltétlenül foglalnak el kevesebb helyet mint a 4 byte-os adatok, valamint a vegyes adatok egyetlen kifejezésben sebesség-problémákat is okozhatnak. Ezért fogadjuk el, hogy amennyiben nem nyilatkozunk másképp, a fordítóprogram int-et fog választani az egész szám literáljaink láttán.

Probléma van akkor, ha az általunk beírt szám meghaladja az int kapacitását, vagyis nagyobb mint 2,147,483,647 (vagy kisebb mint -2,147,483,648). Ez esetben lehetetlen az int választása, mivel ekkora számot nem lehet 4 byte-on előjeles alakban tárolni.

A különös az, hogy a fordító ezt látva sem tér el az alapelvtől: ennek a típusa márpedig int! Megpróbálja 32 biten előjeles tárolni ezt az értéket. Ami történik, az hasonlítható arra, mintha egy másfél liternyi bor tartalmazó kancsó tartalmát egy fél literes edénybe öntjük bele: valami el fog veszni.

Hogy pontosan mi veszik el, és mi lesz az eredménye, annak vizsgálata a Bevezetés az informatikába tárgy keretein belül részletes tárgyalásra, és a fixpontos kettes komplemens módszer alapos ismerete szükséges. Most számunkra csak az a fontos, hogy a számérték amit a program ténylegesen kezelni fog már, az nem az a számérték, amit mi a forráskódban vizuálisan látunk, amit begépeltünk.

Amennyiben ilyen szituációba keverjük a fordítóprogramot, akkor magunkra vessünk. Ha a fordítót ilyen szituációkba ha keverjük, akkor húzzuk is ki belőle! Alkalmazzunk extra típusmódosító jeleket a literál végén:

  • L: módosítás long-ra
  • U: módosítás unsigned-re

Vagyis, a 123 alapból int típusú lenne, de a 123L már 'long típusúként lenne értelmezve. A 123U pedig uint típusú. A 123UL pedig nem más, mint a ulong.

Az u és U jelek egyenlők, vagyis nem kell feltétlenül nagybetűs alakban írni. Hasonlóan a l és L is egyforma ebből a szempontból. Amennyiben mindkét módosítót is használjuk, egymáshoz vett sorrendjük érdektelen, vagyis az LU és UL jelentése megegyezik.

Amennyiben az alapértelmezett int választása nem megfelelő, úgy az L és U módosító jelekkel tudjuk a fordítót más típus választására kényszeríteni. Ez szükséges lehet olyan esetben, amikor az int választás hibás, a literál értéke nem ábrázolható ebben a típusban.


Egész szám literálok 16-os számrendszerbeli alakja

Van arra lehetőségünk, hogy az egész szám értéket ne tizesben, hanem tizenhatos számrendszerben adjuk meg. Erre szükség lehet speciális környezetben, amikor valójában kettes számrendszerben kellene megadni az értéket, de mivel az nem lehetséges, ennek tömörített felírását, a tizenhatos számrendszerbeli megadást kell választanunk.

A tizenhatos számrendszerbeli alak a 0x előtagről ismerszik fel, pl.: 0x012F. A 0x után következhet maximum négy darab, 16-os számrendszerbeli számjegy, melyek a 0,1,..,9,A,B,C,D,E,F karakterek.

A 2*r*Pi kifejezés is felírható lenne 0x02*r*Pi alakban, de ez itt inkább értelmetzavaró lenne, hiszen ez nem az a környezet, ahol a tizenhatos számrendszerbeli alakra szükség van. Azonban hardware közeli, vagy operációs rendszer mélységébe merészkedő programkódokban gyakran van szükség bit-szintű adatkezelésre. A 0x3A tizesben is megadható: 58, de a 0x35 alakban egy hozzáértő azonnal látja, hogy ez a 00111010 bitsorozat, melyet az 58 érték nem ilyen olvasható módon fejez ki.

Megj: a tizenhatos számrendszerbeli alakban minden számjegy 4-4 bitet helyettesít. a 3 a 0011, az 5 pedig a 1010 jelsorozatnak felel meg. Ezért a 35 megfelelője a 0011-1010 jelsorozat.

Tört szám literálok

A tört szám literálok alakjuk szerint . (pont) karaktert tartalmaznak. Például 3.24, vagy -124.2356 vagy 0.0023. Ugyan nálunk, Magyarországon a tizedesvessző van használva tizedespont helyett, de a programozási nyelvek gyakorlatilag mindegyike a tizedespontot használja. Ez még csak nem is területi beállítás-függő. Nem megoldható, hogy egy magyar operációs rendszerrel felszerelt magyar programozó tizedesvesszőt használhasson a tört szám literálokban, mivel az általa megírt C# forráskód nem lehet ilyen beállításfüggő. Ugyanezt forráskódot változatlan alakban le kell tudni fordítani bármely más számítógépen, bármely más nyelven beszélő programozónál is.

A tört szám literálok alakjában tizedespont fedezhető fel. Ezért a 10.0 mindenképpen tört szám literálnak minősül, függetlenül attól, hogy értéke egész szám matematikai szempontból. A forráskódban a tizedespontot kell használni, függetlenül attól, hogy a fordítóprogram jelenleg egy magyar nyelvű, magyar területi beállításokkal rendelkező operációs rendszeren fut.


A tört szám literálok kétféle alakban adhatók meg:

  • közönséges alakban
  • normál alakban

A közönséges alak közismert: 123.456 például egy ilyen alakú tört érték. Lehet negatív is, ekkor - jellel kell kezdeni: -123.456.

A normál alakra hozás hasonló, de a tizedespont előtt ekkor csak egy számjegy állhat: 1.23456*10^2. Vagy a 0.00012 normál alakja a 1.2*10^-4. Ezt az alakot a C# forráskódban nem pontosan így kell megadni, helyette: 1.23456E02, vagy 1.2E-4 formában, vagyis a *10^ jelsorozatot az E karakterre kell cserélni. Az E karakter az exponential, kitevő szóra utal.

A tört szám literálok mindíg double típuskén kerülnek értelmezésre, függetlenül attól, hogy közönséges alakban, vagy normál alakban kerülnek be a program szövegébe.


A literálok végére kerülhet két típusmódosító betű, hasonlóan az egész szám literálok végén opcionálisan szereplő L, U módosítókhoz:

  • F vagy f: float típusmódosító
  • D vagy d: double típusmódosító

Az F módosítóval tudunk float típusú értéket megadni: 12.34f. A D módosítónak első pillanatban nem látjuk értelmét, mivel az alapértelmezett típus is ez, tehát a 12.345D ugyanaz, mint a d nélküli alakja, a 12.345. Ugyanakkor figyeljük meg az alábbit: 12D. Ez a d módosító nélkül int típusú egész szám literál lenne. Ugyanakkor persze a 12.0 is ugyanazt a szerepet képes betölteni, ez is double típusú literál lenne (igaz, ez egy karakterrel hosszabb, mint a 12D).

Logikai literálok

A logikai literálokból összesen kettő létezik: a true és a false. Ezeket ebben a formába, csupa kisbetűs alakban kell beíni a program szövegében.

A true képviseli az igaz, a false képviseli a hamis értéket.

Karakter literálok

A karakter literálok szintén formájukból ismerszenek meg. A karakter literálokat aposztrófok ' között kell megadni. Pl.: 'A', vagy '%'.

Korábban lett említve, hogy a karaktereket UNICODE táblázat szerinti számkódjuk alakjában kerülnek tényleges tárolásra. Ezen táblázatban 65536 különböző karakter van, melyek nem mindegyike van a billentyzűzetre felfestve, bevitelük direkt módon a billentyűzetről nem megoldható. Ezeket a karaktereket alapvetően kétféleképpen írhatjuk be literál alakban:

  • per-jel segítségével
  • kódjukkal

Történelmi okoknál fogva néhány karakter, amelynek speciális jelentést tulajdonítottak, speciális módon, per-jel ('\') segítségével írható be. Néhány karakter ezek közül:

  • \0 <- null karakter, számkódja 0
  • \v <- vertical tab (függőleges tabulátor), számkódja 8
  • \t <- horizontal tab (vizszintes tabulátor), számkódja 9
  • \n <- new line (új sor) karakter, számkódja 10
  • \f <- form feed (lapdobás), számkódja 12
  • \r <- carriage return (kocsi vissza) karakter, számkódja 13
  • \' <- ' karakter
  • \" <- " karakter
  • \\ <- \ karakter

Ez azt jelenti, hogy a '\n' egy karakter literál, a 10-es kódú karaktert írjuk le vele.

Jegyezzük meg, hogy a formának nincs értelme, mivel az aposztrófok jelenléte karakterliterálra utal, de a két aposztróf között nincs leírva melyik literálra gondolunk.

Ugyanakkor a per jelnek egyéb haszna is van. Ha magát az aposztróf karaktert akarnánk mint karakter literál leírni, a ''' módon ezt nem tehetnénk meg. Ugyanis a fordítóprogram az első ' olvasásakor feltételezné, hogy karakterliterál fog következni, melyet a következő ' jelig fog majd megtalálni. De rögtön jön a következő ', s nem találná a két aposztróf között meg milyen karakterliterálra is gondolunk ( esete). Magát a ' karaktert literál alakban a '\ formában kell leírni (később hasonló gondunk lesz a " karakterrel is a string-literálok kapcsán, ezért előrebocsájtjuk, hogy magát a " karaktert is \" alakban kell leírni).

Jegyezzük meg, hogy nem írhatunk bármit a \ jel után. A \w például értelmetlen kapcsolat, nem jelöl semmilyen más karaktert. Az ilyen próbálkozásokat a fordítóprogram szintaktikai hibaként értelmezi.

E miatt a \ karakternek speciális értelme van: azt jelöli, hogy utána egy újabb betű (karakter) következik, és a valódi karakerliterál-értéket ezen rákövetkező betű fogja eldönteni. De mi van ha magát a \ karaktert akarjuk leíni? A '\' forma mostmár azért nem működne, mert a \' sajátságos jelentéssel bír: magát a ' karaktert jelöli. Ekkor viszont a karakterliterálunk nyitó ' aposztrófját nem követi záró aposztróf, e miatt hibás az egész. Magát a \ jelet emiatt duplázni kell: \\ alakban (pontosabban '\\' alakban) kell beírni.

Láthatjuk, hogy a per-jeles alak megkönnyíti néhány speciális (és gyakran használt) karakterliterál bevitelét, de valójában elég sok gondot is okoz. Ugyanakkor ez az alak továbbra sem teszi lehetővé mind a 65536 karakter beírását. További módszerekre is szükség van:

  • ASCII kóddal történő beírás
  • UNICODE kóddal történő beírás

A két módszer gyakorlatilag megegyezik, mindkét esetben lényegében a kívánt karakter számkódját kell beírni, mindkét esetben hexadecimális alakban. A különbség csak annyi, hogy az ASCII kódok maximum 255 értékűek, vagyis hexadecimális alakjuk 2 számjegyből áll (00.FF), a UNICODE kódok 0..65535 közötti értékek, hexadecimális alakjuk 4 számjegyűek (0000..FFFFF).

ASCII kódú beírás esetén \x-el kell kezdeni, és feltüntetni a szükséges számkódot. Például a '\x3F' a 63-s kódú karakter-literál, a '\x20' a 32-es karakter.

UNICODE kódú beírás esetén \u-val (vagy \U -val) kell kezdeni, és 4 hexadecimális számjegynek kell követnie. Például a '\u0F12' egy ilyen módon megadott, valójában a 3858-as kódú karaktert leíró literál.

String literálok

A string literálok alakilag " határolójelek közötti karakter-literál sorozatok. Vagyis a "hello" egy 5 karakterből álló string literál. A "Alma\'fa" pedig egy 7 karakterből álló, ahol a \' jelöli magát az aposztróf karaktert.

További példák:

  • "Hello\x20mama" a helló mama szöveg, mivel a \x20 a 32-es kódú karaktert jelöli, amely a szóköz karakter kódja.
  • "C:\\adatok.dat", ahol a \\ jel jelöli az egyszeres perjelet, tehát egyébként a c:\adatok.dat file-nevet írtuk le.

Különösen file nevek esetén kell nagyon figyelni, pontosan a miatt, hogy a Windows rendszerek alatt \ jellel választjuk el az alkönyvtárneveket egymástól. Egy file névben minden esetben duplázni kell a \ jelet. Ennek elmulasztása érdekes eredményekre vezethet: a "c:\\zenek\nepzenek.lst" filenévben az első \\ jel az egyszeri perjelet írja le, ezzel nincsen gond. Azonban a második esetben a \n véletlenül létező per-jeles kapcsolat, a 10-es kódú karaktert jelöli. Ennek megfelelően ezt a file-t a diszken nem fogjuk megtalálni, létrehozása sem feltétlenül lehetséges, mivel tiltott karakternek minősül file-névben. Ezen hiba kiszűrése, megtalálása némi gondolkodást, és időt vesz el. Egyszerűbb ha odafigyeléssel eleve el sem követjük ezeket a hibákat.

String literál felépítése során karakter literál sorozatot írunk be idézőjelek között. Minden egyes karakternek az idézőjelek belsejében önállóan is meg kell állni a helyét mint karakterliterál. E miatt használhatóak a per-jeles kapcsolatok, kombinációk is.


Persze nagyon zavaró is lehet a folytonos \\ karakter-duplázások. Ezt szerencsére ki lehet váltani egy, a " jel előtt szerepeltetett @ karakterrel:

@"c:\zenek\nepzenek.lst" string literál belsejében szereplő \ karaktereket nem tekinti speciális karakternek a fordító, ezért nem vizsgálja a \z és \n kapcsolatok jelentését - a \ jel egyszerűen \ jelet jelent.

Amennyiben a @ jellel ezt ilyen formára állítjuk, úgy persze elesünk attól a lehetőségtől, hogy a per-jeles beviteli módot használni tudjuk. Nem tudunk például \' sem \" formában bevinni az aposztrófokat sem, nem is beszélve a \x vagy \u kombinációkkal direkt karakterkódokat sem.

String literál idézőjele előtt szereplő kukac jel (@ jel) kikapcsolja a \ karakterek speciális értelmezését. E pillanattól kezdve nem kell a perjelet \\ alakban beírni, de kikapcsoltuk azt a lehetőséget is, hogy a per-jeles kapcsolatok, kombinációkat használni tudjuk.



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