A számítástechnikában a típuskonverzió (type conversion), a típusváltás (type casting), a típuskényszerítés (type coercion) és a típus-zsonglőrködés (type juggling) különböző módjai egy kifejezés megváltoztatásának egyik adattípusról egy másikra. Ilyen például egy egész szám értékének lebegőpontos értékké történő átalakítása vagy szöveges ábrázolása karakterláncként, és fordítva. A típuskonverziók kihasználhatják a típushierarchiákAz osztályhierarchia vagy öröklési fa az informatikában az objektumtípusok osztályozása, amely az objektumokat az osztályok példányaként jelöli és a különböző osztályokat olyan kapcsolatokkal kapcsolja össze, mint az „örökli”, „kiterjeszti”, „absztrakciója”, „interfészdefiníció”. vagy adatreprezentációk bizonyos jellemzőit. A típuskonverzió két fontos szempontja az, hogy implicit (automatikus) vagy explicit módon történik-e, és hogy az alapul szolgáló adatreprezentáció egyik reprezentációból egy másikba kerül-e át, vagy egy adott reprezentációt csupán egy másik adattípus reprezentációjaként értelmezünk át. Általában mind a primitív, mind az összetett adattípusok konvertálhatók.
Minden programozási nyelvnek megvannak a saját szabályai arra vonatkozóan, hogy a típusok hogyan konvertálhatók. Az erős tipizálású nyelvek jellemzően kevés implicit konverziót végeznek, és elriasztják a reprezentációk újraértelmezését, míg a gyenge tipizálású nyelvek sok implicit konverziót végeznek az adattípusok között.A programozási nyelvek besorolásának egyik módja az, hogy a nyelv típusrendszere erősen típusos, vagy gyengén (lazán) típusos-e. A gyengén típusos nyelvek gyakran lehetővé teszik, hogy a fordítót arra kényszerítsék, hogy egy adatelemet önkényesen úgy értelmezzen, hogy különböző reprezentációkkal rendelkezik — ez lehet egy nem nyilvánvaló programozási hiba, vagy egy technikai módszer a mögöttes hardver közvetlen kezelésére.
A legtöbb nyelvben a kényszerítés (coercion) szót használják az implicit konverzípuskonverzióió jelölésére, akár a fordítás, akár a futás során. Például egy olyan kifejezésben, amelyben egész és lebegőpontos számok keverednek (például 5 + 0,1), a fordító automatikusan átalakítja az egész számok ábrázolását lebegőpontos ábrázolásra, hogy a törtek ne vesszenek el. Az explicit típuskonverziókat vagy további kód írásával (pl. típusazonosítók hozzáadásával vagy beépített rutinok hívásával), vagy a fordító által használt konverziós rutinok kódolásával jelezzük, amikor egyébként típuseltérés esetén megállna.
A legtöbb ALGOL-szerű nyelvben, például a Pascalban, a Modula-2-ben, az Adában és a Delphiben a conversion és a casting egymástól jelentősen eltérő fogalmak. Ezekben a nyelvekben a konverzió arra utal, hogy egy értéket implicit vagy explicit módon átváltoztatunk egy adattípus tárolási formátumáról egy másikra, például egy 16 bites egész számot 32 bites egész számra. A konverzió eredményeképpen a tárolási igények megváltozhatnak, beleértve a pontosság esetleges csökkenését vagy a csonkítást. A cast szó viszont arra utal, hogy az értéket reprezentáló bitmintázat értelmezését kifejezetten megváltoztatjuk az egyik típusról a másikra. Például 32 egybefüggő bitet lehet 32 elemű Boolean tömbként, 4 bájtos karakterláncként, előjel nélküli 32 bites egész számként vagy IEEE egyszeres pontosságú lebegőpontos értékként kezelni. Mivel a tárolt bitek soha nem változnak, a programozónak ismernie kell az alacsony szintű részleteket, például az ábrázolási formátumot, a bájtsorrendet és az igazítási igényeket, hogy értelmesen tudjon kasztolni.
A C nyelvcsaládban és az ALGOL 68-ban a cast szó jellemzően explicit típuskonverzióra utal (szemben az implicit konverzióval), ami némi kétértelműséget okoz azzal kapcsolatban, hogy ez egy bitmintázat újraértelmezése-e vagy valódi adatreprezentációs konverzió. Ennél fontosabb az a sokféle mód és szabály, amely arra vonatkozik, hogy egy mutató milyen adattípust (vagy osztályt) talál, és hogy a fordító hogyan állíthatja be a mutatót olyan esetekben, mint például az objektum (osztály) öröklés.
Explicit casting különböző nyelveken Ada Az Ada egy általános Unchecked_Conversion könyvtárfüggvényt biztosít.
C-szerű nyelvek Implicit típuskonverzió Az implicit típuskonverzió, más néven coercion vagy type juggling, a fordító által végzett automatikus típuskonverzió. Egyes programozási nyelvek lehetővé teszik a fordítóprogramok számára a kényszerítést; mások megkövetelik azt.
Egy vegyes típusú kifejezésben az egy vagy több altípushozAz altípus a típuspolimorfizmus egyik formája. tartozó adatok szükség szerint futásidőben átalakíthatók egy szupertípussá, hogy a program megfelelően fusson. A következő például legális C nyelvű kód:
double d; long l; int i;
if (d > i) d = i; if (i > l) l = i; if (d == l) d *= 2;
Bár d, l és i különböző adattípusokhoz tartoznak, minden egyes összehasonlítás vagy hozzárendelés végrehajtásakor automatikusan azonos adattípusokká konvertálódnak. Ezt a viselkedést óvatosan kell használni, mivel nem kívánt következményekkel járhat. A lebegőpontosról egész számra történő átalakításkor adatvesztés következhet be, mivel a lebegőpontos értékek tört összetevői le lesznek csonkítva (nullára kerekítve). Ezzel szemben a pontosság elveszhet az egész számról a lebegőpontosra való átalakítás során, mivel egy lebegőpontos típus nem képes pontosan reprezentálni egy egész szám típus minden lehetséges értékét. Például a float lehet egy IEEE 754-es, egyszeres pontosságú típus, amely nem tudja pontosan ábrázolni a 16777217 egész számot, míg egy 32 bites egész szám típus képes erre. Ez nem intuitív viselkedéshez vezethet, amint azt a következő kód mutatja:
#include <stdio.h>
int main(void) { int i_value = 16777217; float f_value = 16777216.0; printf("The integer is: %d\n", i_value); printf("The float is: %f\n", f_value); printf("Their equality: %d\n", i_value == f_value); }
Az olyan fordítóprogramokon, amelyek a lebegőpontos számokat IEEE egyszeres pontossággal, az int-eket pedig legalább 32 bites pontossággal implementálják, ez a kód ezt a furcsa kiírást fogja eredményezni:
The integer is: 16777217 The float is: 16777216.000000 Their equality: 1
Vegyük észre, hogy a fenti utolsó sorban az 1 az egyenlőséget jelenti. Ezt a furcsa viselkedést az i_value implicit átalakítása float értékké okozza, amikor f_value értékkel hasonlítjuk össze. A konverzió pontosságvesztést okoz, ami az értékeket az összehasonlítás előtt egyenlővé teszi.
Fontos tanulságok: A float átváltása int értékre csonkítást okoz, azaz a tört rész eltávolítását. A double átváltása float értékre a számjegy kerekítését okozza. long-ból int-be a felesleges magasabb rendű bitek kiesését okozza.
Típuspromóció Az implicit típuskonverzió egyik speciális esete a típuspromóció, amikor egy objektum automatikusan átalakul egy másik adattípussá, amely az eredeti típus szuperhalmazát képviseli. Az előléptetést általában a célplatform aritmetikai-logikai egységének (ALU) natív típusánál kisebb típusoknál használják, az aritmetikai és logikai műveletek előtt, hogy lehetővé tegyék az ilyen műveleteket, vagy hatékonyabbá tegyék, ha az ALU több típussal is képes dolgozni. A C és a C++ a Boolean, a karakter, a széles karakter, a felsorolásA felsorolt típus (enumerated type) egy adattípus, amely elnevezett értékek halmazából áll. és a rövid egész szám típusú objektumok esetében int-re, a float típusú objektumok esetében pedig double-ra léptetik elő. Néhány más típuskonverzióval ellentétben a promóciók soha nem veszítik el a pontosságot, és nem módosítják az objektumban tárolt értéket.
Java-ban:
int x = 3; double y = 3.5; System.out.println(x + y); // The output will be 6.5
Explicit típusátalakítás Az explicit típuskonverzió, más néven típusváltás (type casting), olyan típuskonverzió, amelyet a programban explicit módon definiálnak (ahelyett, hogy az implicit típuskonverzió esetén automatikusan, a nyelv szabályai szerint történne). Ezt a felhasználó kéri a programban.
double da = 3.3; double db = 3.3; double dc = 3.4; int result = (int)da + (int)db + (int)dc; // result == 9 // if implicit conversion would be used (as with "result = da + db + dc"), result would be equal to 10
Többféle explicit konverzió létezik. checked A konverzió végrehajtása előtt futásidejű ellenőrzés történik, hogy a céltípus képes-e megtartani a forrásértéket. Ha nem, akkor hibaállapot lép fel. unchecked Nem történik ellenőrzés. Ha a céltípus nem tudja tárolni a forrásértéket, az eredmény nem meghatározott. bit pattern A forrás nyers bitreprezentációja szó szerint átmásolásra kerül, és a céltípusnak megfelelően újraértelmezésre kerül. Ez aliasing segítségével is megvalósítható.A számítástechnikában az aliasing olyan helyzetet ír le, amikor egy memóriában lévő adathelyet a programban különböző szimbolikus neveken keresztül lehet elérni.
Az objektumorientált programozási nyelvekben az objektumokat lefelé is lehet kasztolni (downcast) : egy bázisosztály hivatkozása a származtatott osztályok egyikére castolható.Az osztályalapú programozásban a downcasting vagy típusfinomítás az alap- vagy szülőosztály-hivatkozásnak egy szűkebb származtatott osztályhivatkozásra való átváltása.
C# és C++ A C# nyelvben a típuskonverzió történhet biztonságos vagy nem biztonságos (azaz C-szerű) módon, az előbbit ellenőrzött típuskonverziónak nevezzük. at C# Tutorial
Animal animal = new Cat();
Bulldog b = (Bulldog) animal; // if (animal is Bulldog), stat.type(animal) is Bulldog, else an exception b = animal as Bulldog; // if (animal is Bulldog), b = (Bulldog) animal, else b = null
animal = null; b = animal as Bulldog; // b == null
C++-ban hasonló hatás érhető el a C++ stílusú cast szintaxissal.
Animal* animal = new Cat;
Bulldog* b = static_cast<Bulldog*>(animal); // compiles only if either Animal or Bulldog is derived from the other (or same) b = dynamic_cast<Bulldog*>(animal); // if (animal is Bulldog), b = (Bulldog*) animal, else b = nullptr
Bulldog& br = static_cast<Bulldog&>(*animal); // same as above, but an exception will be thrown if a nullptr was to be returned // this is not seen in code where exception handling is avoided
delete animal; // always free resources animal = nullptr; b = dynamic_cast<Bulldog*>(animal); // b == nullptr
Eiffel Az Eiffelben a típuskonverzió fogalma beépült a típusrendszer szabályaiba. A hozzárendelési szabály azt mondja ki, hogy egy hozzárendelés, mint pl:
x := y
akkor és csak akkor érvényes, ha a forráskifejezésének típusa, ebben az esetben y, kompatibilis a célentitás típusával, ebben az esetben x-szel. Ebben a szabályban a kompatibilis azt jelenti, hogy a forráskifejezés típusa vagy megfelel a céltípus típusának, vagy átalakul a céltípus típusává. A típusok konformitását az objektumorientált programozásban a polimorfizmus ismert szabályai határozzák meg. Például a fenti hozzárendelésben y típusa megfelel x típusának, ha az osztály, amelyen y alapul, leszármazottja annak az osztálynak, amelyen x alapul.
A típusátalakítás definíciója az Eiffelben Az Eiffelben a típuskonverzió műveletei, konkrétan a converts to és converts from a következőképpen vannak definiálva: Egy CU osztályon alapuló típus átalakul egy CT osztályon alapuló T típussá (és T alakítja át U-ból), ha valamelyik CT rendelkezik egy konverziós eljárással, amely U-t használ konverziós típusként, vagy A CU rendelkezik egy konverziós lekérdezéssel, amely a T-t konverziós típusként sorolja fel.
Példa