Datový typ ( type ) je sada hodnot a operací s těmito hodnotami (IEEE Std 1320.2-1998) [1] .
Další definice:
Typ definuje možné hodnoty a jejich význam, operace a způsob uložení hodnot typu. Studováno teorií typů . Nedílnou součástí většiny programovacích jazyků jsou typové systémy , které používají typy k zajištění určitého stupně bezpečnosti typu .
Datový typ zároveň charakterizuje:
Na první vlastnost lze pohlížet jako na množinově teoretickou definici pojmu typu; druhá je jako procedurální (nebo behaviorální) definice.
Kromě toho se v programování používá nízkoúrovňová definice typu - jako dané rozměrové a strukturální charakteristiky paměťové buňky, do které lze umístit určitou hodnotu odpovídající těmto charakteristikám. Taková definice je speciálním případem té množinově teoretické. V praxi je s tím spojena řada důležitých vlastností (kvůli zvláštnostem organizace počítačové paměti ), které vyžadují zvláštní zvážení .
Definice teorie množin, zejména v její nízkoúrovňové variantě, se nejčastěji používá v imperativním programování . Procedurální definice je více spojena s parametrickým polymorfismem . Objektově orientované programování používá procedurální definici při popisu interakce programových komponent a množinovou definici při popisu implementace těchto komponent na počítači, v tomto pořadí, s ohledem na „ třídu jako chování “ a „ třídu jako objekt v paměti “. " .
Operace přiřazení typu informačním entitám se nazývá typování . Přiřazení a kontrolu konzistence typu lze provést předem ( statické typování ), přímo při použití ( dynamické typování ) nebo kombinací obou metod. Typy mohou být přiřazeny "jednou provždy" ( silné psaní ) nebo mohou být změněny ( slabé psaní ).
Typy se vyhýbají Russellovu paradoxu , zejména Church zavedl typy do lambda kalkulu právě pro tento účel [6] .
V přirozeném jazyce jsou tázací zájmena zodpovědná za psaní .
Jednotné zacházení s daty různých typů se nazývá polymorfismus [7] [8] .
Koncept typové bezpečnosti se opírá především o procedurální definici typu. Například pokus o dělení čísla řetězcem bude většinou jazyků odmítnut, protože pro tyto typy není definováno žádné odpovídající chování. Slabě napsané jazyky mají tendenci být nízkoúrovňové definice. Například „ číslo “ a „ záznam “ mají odlišné chování, ale hodnota adresy „ záznam “ v paměti počítače může mít stejnou nízkoúrovňovou reprezentaci jako „číslo“. Slabě typované jazyky poskytují schopnost prolomit typový systém přiřazením " čísla " k hodnotě pomocí operace přetypování . Takové triky lze použít ke zvýšení efektivity programů, ale přinášejí riziko selhání , a proto nejsou povoleny v bezpečných jazycích nebo jsou přísně izolované.
Existují různé klasifikace typů a pravidla pro jejich přiřazení.
Analogicky s matematikou se datové typy dělí na skalární ( primitivní ) a neskalární ( agregované ). Hodnota neskalárního typu (neskalární hodnota) má mnoho uživatelsky viditelných komponent, zatímco hodnota skalárního typu (skalární hodnota) nikoli. [9] Příklady neskalárního typu jsou pole , seznamy a tak dále; příklady skalárního typu jsou „ integer “, „ boolean “ atd.
Strukturální (agregátní) typy by neměly být ztotožňovány s datovými strukturami : některé datové struktury jsou přímo ztělesněny určitými strukturálními typy, ale jiné jsou vytvářeny prostřednictvím jejich složení, nejčastěji rekurzivního. V druhém případě se hovoří o rekurzivních datových typech . Příkladem datových struktur, které jsou téměř vždy vytvářeny prostřednictvím objektové kompozice rekurzivního typu, jsou binární stromy .
Podle jiné klasifikace se typy dělí na nezávislé a závislé . Důležitými odrůdami posledně jmenovaných jsou referenční typy , které jsou zase ukazateli . Reference (včetně ukazatelů) jsou nesloženým závislým typem, jehož hodnoty jsou adresami v paměti počítače jiné hodnoty. Například v systému typu C se typ „ ukazatel na celé číslo bez znaménka “ zapíše jako „ unsigned *“ , v jazyce ML se typ „ odkaz na celé číslo bez znaménka “ zapíše jako „ word ref“ .
Typy se také dělí na monomorfní a polymorfní (viz typová proměnná ).
Logické neboli booleovské hodnoty (podle jména jejich vynálezce – Boole) mohou mít pouze jeden ze dvou stavů – „true“ nebo „false“. boolV různých jazycích jsou označeny ,, BOOLnebo boolean. "Pravda" může být označena jako true, TRUEnebo #T. "False", respektive false, FALSEnebo #F. V C a C++ je každé nenulové číslo považováno za pravdivé a nula za nepravdivé. V Pythonu mají některé jednotlivé typy také přiřazenu hodnotu "boolean". K implementaci typu v zásadě stačí jeden bit, ale vzhledem k povaze mikroprocesorů se v praxi velikost booleovských hodnot obvykle rovná velikosti strojového slova .
Integer typy obsahují hodnoty interpretované jako čísla (se znaménkem a bez znaménka).
Používá se k reprezentaci reálných (ne nutně celých) čísel. V tomto případě je číslo zapsáno jako x=a*10^b. Kde 0<=a<1 a b je nějaké celé číslo z určitého rozsahu. a se nazývá mantisa, b je řád. Mantisa ukládá několik číslic za desetinnou čárkou a b je uloženo celé.
Posloupnost znaků, se kterou se v kontextu proměnné zachází jako s celkem. Různé programovací jazyky ukládají různá omezení na proměnné řetězce. Řetězce mohou obsahovat sekvence escape .
Ukazatel je proměnná, jejíž rozsah hodnot se skládá z adres paměťových míst nebo speciální hodnoty, která označuje, že v proměnné není aktuálně nic uloženo.
Typy identit nejsou interpretovány jako číslo, ale jako jedinečný identifikátor objektu. Například FourCC .
Datové typy, které jsou brány v úvahu bez ohledu na kontext a implementaci v konkrétním programovacím jazyce. Abstrakce v matematickém smyslu znamená, že algebra dat je zpracována až do izomorfismu . Abstraktní typy jsou široce používány v metodologii programování založené na postupném vývoji programu. Ve fázi konstrukce specifikace navrženého programu datová algebra modeluje objekty předmětné oblasti z hlediska řešeného problému. V procesu postupného zpřesňování jsou data konkretizována předáváním přechodným reprezentacím, dokud není nalezena jejich implementace pomocí základní datové algebry použitého programovacího jazyka. Existuje několik způsobů, jak definovat abstraktní typy: algebraické, modelové a axiomatické. V modelovém přístupu jsou datové prvky definovány explicitně. Algebraický přístup využívá metody algebraických vztahů, zatímco axiomatický přístup používá logickou formalizaci.
Typ může být parametrizován jiným typem, v souladu s principy abstrakce a parametricity . Například pro implementaci funkce pro řazení sekvencí není nutné znát všechny vlastnosti jejích prvků – stačí, aby umožňovaly srovnávací operaci – a pak lze složený typ „ sekvence “ definovat jako parametricky polymorfní . . To znamená, že jeho komponenty nejsou definovány pomocí konkrétních typů (jako je " celé číslo " nebo " pole celých čísel "), ale pomocí parametrů typu. Takové parametry se nazývají typové proměnné ( anglicky type variable ) - používají se v definici polymorfního typu stejně jako hodnotové parametry v definici funkce. Nahrazením konkrétních typů jako skutečných parametrů za polymorfní typ vznikne monomorfní typ. Parametricky polymorfní typ je tedy typový konstruktor , tj. operátor typů v aritmetice typů.
Definovat třídicí funkci jako parametricky polymorfní znamená, že třídí abstraktní sekvenci, tedy posloupnost prvků nějakého (neznámého) typu. V tomto případě funkce potřebuje znát pouze dvě vlastnosti o svém parametru - že se jedná o sekvenci a že pro její prvky je definována operace porovnání . Zvažování parametrů spíše procedurálním než deklarativním způsobem (tj. jejich použití na základě chování spíše než hodnoty) vám umožňuje použít jedinou třídicí funkci pro jakékoli sekvence – pro sekvence celých čísel, pro sekvence řetězců, pro sekvence sekvencí booleovských hodnot. hodnoty a tak dále – a výrazně zvyšuje faktor opětovného použití kódu . Dynamické psaní poskytuje stejnou flexibilitu , ale na rozdíl od parametrického polymorfismu přichází s režií. Parametrický polymorfismus je nejrozvinutější v jazycích typu Hindley-Milner , tedy potomcích jazyka ML . V objektově orientovaném programování se parametrický polymorfismus nazývá generické programování .
Navzdory zřejmým výhodám parametrického polymorfismu je někdy nutné zajistit různé chování pro různé podtypy stejného obecného typu nebo podobné chování pro nekompatibilní typy - tedy v nějaké formě ad-hoc polymorfismu . Neexistuje však pro něj matematický základ, takže požadavek na typovou bezpečnost ztěžoval používání na dlouhou dobu. Ad-hoc polymorfismus byl implementován v rámci systému parametricky polymorfního typu pomocí různých triků. K tomuto účelu byly použity buď variantní typy [ , nebo parametrické moduly ( funktory nebo tzv. „ typově indexované hodnoty “), které mají zase řadu implementací [ 10 ] . jazyk Haskell poskytl elegantnější řešení tohoto problému.
Pokud je dotyčnou informační entitou typ, pak přiřazení typu k ní povede ke konceptu „ typu typu “ („ metatyp “). V teorii typů se tento koncept nazývá „ druh typů “ ( angl. druh typu nebo typ typu ). Například rod „ *“ zahrnuje všechny typy a rod „ * -> *“ zahrnuje všechny konstruktory unárních typů . Gendery se explicitně používají v typovém programování , například jako konstruktory typů v jazycích rodiny ML .
Rozšíření systému bezpečných polymorfních typů na třídy a typové rody udělalo z Haskell první plně typovaný jazyk. Výsledný typový systém ovlivnil další jazyky (např. Scala , Agda ).
Omezená forma metatypů je také přítomna v řadě objektově orientovaných jazyků ve formě metatříd . V potomcích jazyka Smalltalk (jako je Python ) je každá entita v programu objektem, který má typ, který je sám objektem – metatypy jsou tedy přirozenou součástí jazyka. V jazyce C++ je subsystém RTTI implementován odděleně od hlavního typového systému jazyka , který také poskytuje typové informace ve formě speciální struktury.
Dynamické objasňování metatypů se nazývá reflexe (a také reflexivita či introspekce).
Nejnápadnějším rozdílem mezi skutečným programováním a formální teorií informace je zohlednění otázek efektivity nejen z hlediska O-notace , ale také z hlediska ekonomické proveditelnosti implementace určitých požadavků do fyzicky vyrobeného počítače . A především to ovlivňuje přípustnou přesnost výpočtů: pojem „číslo“ v počítači v praxi není totožný s pojmem čísla v aritmetice . Číslo v počítači představuje paměťová buňka , jejíž velikost je určena architekturou počítače a rozsah hodnot čísla je omezen velikostí této buňky. Například procesory architektury Intel x86 poskytují buňky, jejichž velikost v bajtech je nastavena na mocninu dvou: 1, 2, 4, 8, 16 atd. Procesory architektury Setun poskytují buňky, jejichž velikost ve vlastnostech je nastavena na násobek tří: 1, 3, 6, 9 atd.
Pokus zapsat do buňky hodnotu, která překračuje pro ni maximální povolený limit (který je známý ), má za následek chybu přetečení . Pokud je potřeba počítat na větší čísla, používá se speciální technika zvaná dlouhá aritmetika , kterou nelze kvůli značné náročnosti na zdroje provádět v reálném čase. Pro nejběžnější počítačové architektury v současnosti je „nativní“ velikost buňky 32 a 64 bitů (tj. 4 a 8 bajtů ).
Kromě toho mají celá čísla a reálná čísla v těchto buňkách různé reprezentace: nezáporná celá čísla jsou reprezentována přímo , záporná celá čísla jsou reprezentována dvojkovým doplňkem a reálná čísla jsou zakódována speciálním způsobem . Kvůli těmto rozdílům je sčítání čísel " 1" a " 0.1", které teoreticky dává hodnotu " 1.1", na počítači přímo nemožné. Chcete-li jej implementovat, musíte nejprve provést převod typu , vygenerovat 1novou hodnotu skutečného typu „ “ na základě hodnoty typu celého čísla „ 1.0“ a teprve poté přidat „ 1.0“ a „ 0.1“. Vzhledem ke specifikům implementace reálných čísel na počítači se taková transformace neprovádí absolutně přesně, ale s určitou mírou aproximace. Ze stejného důvodu silně typizované jazyky (jako je Standard ML ) považují skutečný typ za rovnocenné typy (nebo typy identity) ( Equality type ).
Pro nízkoúrovňovou reprezentaci kompozitních typů je důležitý koncept zarovnání dat . Vysokoúrovňové jazyky obvykle programátora od této vlastnosti izolují (abstrahují), je však třeba s ní počítat při propojování samostatně sestavených modulů mezi sebou. Některé jazyky ( C -, C++ ) však poskytují možnost ovládat nízkoúrovňovou reprezentaci typů, včetně zarovnání. Takové jazyky se někdy nazývají jazyky střední úrovně.
Typy dat | |
---|---|
Neinterpretovatelné | |
Numerický | |
Text | |
Odkaz | |
Kompozitní | |
abstraktní | |
jiný | |
související témata |