Az adattípus ( típus ) értékek és az ezeken az értékeken végzett műveletek halmaza (IEEE Std 1320.2-1998) [1] .
Egyéb meghatározások:
A típus határozza meg a lehetséges értékeket és azok jelentését, a műveleteket, valamint a típus értékeinek tárolási módját. Típuselmélet alapján tanult . A legtöbb programozási nyelv szerves részét képezik a típusrendszerek , amelyek típusokat használnak bizonyos fokú típusbiztonság biztosítására .
Az adattípus egyben jellemzi:
Az első tulajdonság a típusfogalom halmazelméleti definíciójaként fogható fel; a második mint eljárási (vagy viselkedési) definíció.
Ezenkívül a programozásban egy típus alacsony szintű definícióját alkalmazzák - mint egy memóriacella adott méretbeli és szerkezeti jellemzőit, amelyben ezeknek a jellemzőknek megfelelő bizonyos érték helyezhető el. Az ilyen meghatározás a halmazelméleti definíció speciális esete. A gyakorlatban számos fontos tulajdonság kapcsolódik hozzá (a számítógépes memória felépítésének sajátosságai miatt ), amelyek külön mérlegelést igényelnek .
A halmazelméleti definíciót, különösen annak alacsony szintű változatában, leggyakrabban az imperatív programozásban használják . Az eljárási meghatározás inkább a parametrikus polimorfizmushoz kapcsolódik . Az objektum-orientált programozás procedurális definíciót használ a programkomponensek interakciójának leírására, halmazelméleti definíciót pedig ezeknek az összetevőknek a számítógépen való megvalósításának leírására, figyelembe véve az " osztály mint viselkedés " és az " osztály mint objektum a memóriában " " .
Az információs entitásokhoz típus hozzárendelését gépelésnek nevezzük . A hozzárendelés és a típuskonzisztencia ellenőrzése elvégezhető előre ( statikus gépelés ), közvetlenül a használat során ( dinamikus gépelés ), vagy a két módszer kombinációjával. A típusok hozzárendelhetők "egyszer és mindenkorra" ( erős gépelés ), vagy megváltoztathatók ( gyenge gépelés ).
A típusok elkerülik a Russell-féle paradoxont , nevezetesen Church éppen ebből a célból vezetett be típusokat a lambda-számításba [6] .
A természetes nyelvben a kérdő névmások felelősek a gépelésért .
A különböző típusú adatok egységes kezelését polimorfizmusnak nevezzük [7] [8] .
A típusbiztonság fogalma elsősorban az eljárási típusmeghatározáson alapul. Például egy szám karakterlánccal való felosztására tett kísérletet a legtöbb nyelv elutasítja, mivel ezeknél a típusoknál nincs meghatározva a megfelelő viselkedés. A gyengén gépelt nyelvek általában alacsony szintű definíciók. Például a " szám " és a " rekord " viselkedése eltérő, de a számítógép memóriájában lévő " rekord " címének értéke ugyanolyan alacsony szintű lehet, mint a "szám". A gyengén gépelt nyelvek lehetővé teszik a típusrendszer megszakítását azáltal , hogy " szám " viselkedést rendelnek egy értékhez egy cast művelettel . Az ilyen trükkök felhasználhatók a programok hatékonyságának növelésére, de magában hordozzák az összeomlások kockázatát , ezért biztonságos nyelveken nem engedélyezettek, vagy szigorúan elszigeteltek.
Különféle típusok osztályozása és hozzárendelésük szabályai léteznek.
A matematikával analóg módon az adattípusokat skaláris ( primitív ) és nem skaláris ( összesített ) típusokra osztják . A nem skalár típusú értéknek (egy nem skaláris értéknek) sok a felhasználó által látható összetevője van, míg a skalár típusú értéknek (skalárértéknek) nincs. [9] Példák a nem skaláris típusokra: tömbök , listák és így tovább; a skaláris típusok példái az " integer ", " boolean " stb.
A strukturális (összesített) típusokat nem szabad az adatstruktúrákkal azonosítani : egyes adatstruktúrákat bizonyos struktúratípusok közvetlenül testesítenek meg, míg mások összetételükön keresztül épülnek fel, leggyakrabban rekurzív módon. Ez utóbbi esetben rekurzív adattípusokról beszélünk . A bináris fák olyan adatstruktúrák, amelyek szinte mindig rekurzív típusú objektumösszetételen keresztül épülnek fel .
Egy másik osztályozás szerint a típusokat független és függő kategóriákra osztják . Utóbbiak fontos fajtái a referencia típusok , amelyek viszont mutatók . A hivatkozások (beleértve a mutatókat is) nem összetett függő típusok, amelyek értékei egy másik érték címe a számítógép memóriájában. Például a C típusú rendszerben az " előjel nélküli egész számra mutató mutató " a következővel van írva: " unsigned *" , az ML nyelvben a " hivatkozás előjel nélküli egész számra " típus " word ref" -ként van írva .
A típusokat monomorfra és polimorfra is felosztják (lásd a típusváltozót ).
A logikai vagy logikai értékeknek (feltalálójuk neve után - Boole) csak egy lehet két állapota - "igaz" vagy "hamis". Különböző nyelveken , vagy jelöléssel vannak boolellátva . Az "igazság" , vagy . "Hamis", illetve , vagy . C-ben és C++-ban minden nullától eltérő szám igaznak, a nulla pedig hamisnak minősül. A Pythonban néhány egyedi típushoz "logikai" érték is hozzá van rendelve. A típus megvalósításához elvileg egy bit is elegendő, azonban a mikroprocesszorok természetéből adódóan a gyakorlatban a logikai értékek mérete általában megegyezik egy gépi szó méretével . BOOLbooleantrueTRUE#TfalseFALSE#F
Az egész típusok számként értelmezett értékeket tartalmaznak (előjeles és előjel nélküli).
Valós (nem feltétlenül egész) számok ábrázolására szolgál. Ebben az esetben a számot x=a*10^b alakban írjuk. Ahol 0<=a<1 és b egy bizonyos tartományból származó egész szám. a-t mantisszának hívják, b a sorrendet. A mantissza a tizedesvessző után több számjegyet tárol, a b pedig teljes egészében.
Karakterek sorozata, amelyet a rendszer egészként kezel egy változó kontextusában. A különböző programozási nyelvek eltérő korlátozásokat írnak elő a karakterlánc-változókra. A karakterláncok escape szekvenciákat tartalmazhatnak .
A mutató olyan változó, amelynek értéktartománya memóriahelyek címeiből vagy egy speciális értékből áll, amely jelzi, hogy a változóban jelenleg nincs tárolva semmi.
Az identitástípusokat a rendszer nem számként értelmezi, hanem egyedi objektumazonosítóként. Például FourCC .
Adattípusok, amelyeket a rendszer a kontextustól és az adott programozási nyelvben való megvalósítástól függetlenül veszi figyelembe. A matematikai értelemben vett absztrakció azt jelenti, hogy az adatalgebrát izomorfizmusig kezeljük . Az absztrakt típusokat széles körben használják a lépésről lépésre történő programfejlesztésen alapuló programozási módszertanban. A megtervezett program specifikációjának megalkotásának szakaszában az adatalgebra modellezi a tárgyterület objektumait, a megoldandó probléma szempontjából. A növekményes finomítás során az adatok konkretizálódnak a közbenső reprezentációknak való átadással, amíg a megvalósítást meg nem találjuk a használt programozási nyelv mögöttes adatalgebrájával. Az absztrakt típusok meghatározásának többféle módja van: algebrai, modell és axiomatikus. A modell megközelítésben az adatelemek explicit módon vannak definiálva. Az algebrai megközelítés algebrai kapcsolatok módszereit, míg az axiomatikus megközelítés logikai formalizálást alkalmaz.
Egy típus paraméterezhető más típussal is, az absztrakció és a parametricitás elvének megfelelően . Például egy szekvenciák rendezésére szolgáló függvény megvalósításához nem szükséges ismerni az alkotóelemeinek összes tulajdonságát - csak az szükséges, hogy lehetővé tegyék az összehasonlítási műveletet -, és ekkor az összetett típusú „ szekvencia ” paraméteresen polimorfként definiálható. . Ez azt jelenti, hogy összetevői nem konkrét típusokkal (például " egész szám " vagy " egész számok tömbje ") vannak megadva, hanem típusparaméterekkel. Az ilyen paramétereket típusváltozóknak ( angol type variable ) nevezzük – a polimorf típusok definíciójában ugyanúgy használatosak, mint a függvénydefiníciók értékparaméterei. Ha egy polimorf típus tényleges paramétereként betontípusokat helyettesítünk, akkor monomorf típus jön létre. Így a parametrikusan polimorf típus típuskonstruktor , azaz a típusaritmetika típusainak operátora.
A rendezési függvény parametrikusan polimorfként való meghatározása azt jelenti, hogy egy absztrakt sorozatot, azaz valamilyen (ismeretlen) típusú elemsorozatot rendez. Ebben az esetben a függvénynek csak két tulajdonságot kell tudnia a paraméteréről - azt, hogy sorozatról van szó, és hogy az összehasonlítási művelet az elemeire van definiálva . A paraméterek procedurális, nem pedig deklaratív módon történő figyelembevétele (vagyis a viselkedés, nem pedig az érték alapján történő használata) lehetővé teszi, hogy egyetlen rendezési függvényt használjunk bármilyen sorozathoz – egész számok sorozataihoz, karakterláncok sorozataihoz, logikai sorozatok sorozataihoz. értékek és így tovább – és jelentősen megnöveli a kód újrafelhasználási tényezőjét . A dinamikus gépelés ugyanazt a rugalmasságot biztosítja , azonban a parametrikus polimorfizmussal ellentétben az előbbi többletköltséggel jár. A paraméteres polimorfizmus leginkább a Hindley-Milner-típusú nyelvekben , azaz az ML nyelv leszármazottaiban fejlődött ki . Az objektum-orientált programozásban a parametrikus polimorfizmust általános programozásnak nevezik .
A parametrikus polimorfizmus nyilvánvaló előnyei ellenére néha szükségessé válik, hogy eltérő viselkedést biztosítsunk ugyanazon általános típus különböző , vagy hasonló viselkedést inkompatibilis típusokhoz - vagyis az ad -hoc polimorfizmus valamilyen formájában . Matematikai alapja azonban nincs, így a típusbiztonsági követelmény sokáig nehezítette a használatát. Az ad-hoc polimorfizmust egy parametrikusan polimorf típusú rendszeren belül valósították meg különféle trükkökkel. Erre a célra vagy variáns típusokat , vagy parametrikus modulokat ( functors vagy úgynevezett “ type - indexed value ”) használtak, amelyeknek viszont számos implementációja is van [ 10 ] . a Haskell nyelv elegánsabb megoldást adott erre a problémára.
Ha a kérdéses információs entitás típus, akkor egy típus hozzárendelése a „ típustípus” („ metatípus ”) fogalmához vezet. A típuselméletben ezt a fogalmat „ típustípusnak ” ( eng. type of a type vagy type type ) nevezik. Például a „ *” nemzetségbe tartozik minden típus, a „ * -> *” nemzetségbe pedig minden unáris típusú konstruktor . A nemeket kifejezetten a típusteljes programozásban használják , például típuskonstruktorként az ML család nyelveiben .
A biztonságos polimorf típusrendszer kiterjesztése osztályokra és típusnemzetségekre a Haskell lett az első teljesen tipizált nyelv. Az így létrejövő típusrendszer más nyelvekre is hatással volt (pl. Scala , Agda ).
A metatípusok korlátozott formája számos objektum-orientált nyelvben is jelen van metaosztályok formájában . A Smalltalk nyelv leszármazottaiban (például a Pythonban ) a program minden entitása olyan objektum, amelynek van egy típusa, amely maga is objektum – így a metatípusok a nyelv természetes részét képezik. A C++ nyelvben az RTTI alrendszer a nyelv fő típusrendszerétől elkülönítve kerül megvalósításra , amely egy speciális struktúra formájában típusinformációkat is biztosít.
A metatípusok dinamikus feltárását reflexiónak (és reflexivitásnak vagy introspekciónak is) nevezik.
A legszembetűnőbb különbség a valódi programozás és a formális információelmélet között a hatékonysági kérdések figyelembe vétele nemcsak az O-jelölés szempontjából, hanem bizonyos követelmények fizikailag gyártott számítógépen való megvalósításának gazdasági megvalósíthatósága szempontjából is . És mindenekelőtt ez befolyásolja a számítások megengedett pontosságát: a "szám" fogalma a számítógépben a gyakorlatban nem azonos a szám aritmetikai fogalmával . A számítógépben lévő számot egy memóriacella képviseli , amelynek méretét a számítógép architektúrája határozza meg , és a szám értéktartományát ennek a cellának a mérete korlátozza. Például az Intel x86 architektúra processzorai olyan cellákat biztosítanak, amelyek mérete bájtban kettő hatványra van beállítva: 1, 2, 4, 8, 16 stb . A Setun architektúra processzorai olyan cellákat biztosítanak, amelyek jellemzői mérete egy a három többszöröse: 1, 3, 6, 9 stb.
Túlcsordulási hibát okoz, ha egy cellába olyan értéket írnak, amely meghaladja a számára megengedett maximális határértéket (ami ismert ) . Ha nagyobb számokon kell számolni, akkor egy speciális technikát alkalmaznak, az úgynevezett long aritmetikát , amely a jelentős erőforrás-intenzitás miatt valós időben nem hajtható végre. A jelenleg legelterjedtebb számítógép-architektúrák esetében a „natív” a 32 és 64 bites cellaméret (azaz 4 és 8 bájt ).
Ezen túlmenően ezekben a cellákban az egész számok és a valós számok eltérő módon jelennek meg: a nem negatív egész számokat közvetlenül , a negatív egészeket kettős komplementerben , a valós számokat pedig speciális módon kódolják . Ezen eltérések miatt a " 1" és a " 0.1" számok összeadása, amelyek elméletileg a " 1.1" értéket adják, számítógépen közvetlenül lehetetlen. A megvalósításhoz először egy típuskonverziót kell végrehajtania , létrehozva 1a valódi „ ” típusú új értéket a „ ” egész típus értéke alapján 1.0, és csak ezután kell hozzáadnia a „ 1.0” és a „ 0.1” értéket. A valós számok számítógépen való megvalósításának sajátosságai miatt az ilyen transzformációt nem teljesen pontosan, hanem bizonyos fokú közelítéssel hajtják végre. Ugyanezen okból kifolyólag az erősen tipizált nyelvek (mint például a Standard ML ) a valódi típust egyenlőségtípusként (vagy identitástípusként ) kezelik ( Equality type ).
Az összetett típusok alacsony szintű ábrázolásához fontos az adatillesztés fogalma . A magas szintű nyelvek általában elszigetelik (absztrakt) a programozót ettől a tulajdonságtól, azonban ezt figyelembe kell venni az önállóan lefordított modulok egymáshoz kapcsolásakor. Egyes nyelvek ( C -, C ++ ) azonban lehetővé teszik a típusok alacsony szintű megjelenítését, beleértve az igazítást is. Az ilyen nyelveket néha középszintű nyelveknek is nevezik.
Adattípusok | |
---|---|
Értelmezhetetlen | |
Numerikus | |
Szöveg | |
Referencia | |
Összetett | |
absztrakt | |
Egyéb | |
Kapcsolódó témák |