Např.: do int lze uložit celá čísla ve specifikovaném rozsahu
operací – jak lze s datovými typy pracovat.
Např.: sčítání dvou celých čísel
Každý programovací jazyk definuje svá pravidla pro datové typy
Slouží k tomu, aby bylo jasné co je na dané paměti uloženo
Proměnná – pojmenované místo v paměti, do kterého lze uložit data
Proměnné vždy mají datový typ
Existují pravidla pro tvorbu validních názvů proměnných
Dělení jazyků dle typovosti
Silně typované – každá proměnná musí mít v době kompilace určen svůj datový typ
Určení může být buďto explicitní, nebo jej lze odvodit z kontextu (type-inference)
Př.: C, C#, Java…
Slabě typované – datové typy jsou přítomné až v runtime
Datový typ není nutné explicitně specifikovat
Př.: JavaScript
Dělení datových typů
Dle struktury
Jednoduché datové typy – jedná se o základní (elementární) datové typy
Tvoří se z nich později komplexnější typy (viz. strukturované datové typy)
Př.: int, float, char …
Strukturované (komplexní) datové typy – slouží k uložení jedné nebo více souvisejících hodnot
Mohou obsahovat jednoduché datové typy nebo jiné strukturované datové typy. Např. třída může obsahovat proměnné typu int a char a zároveň i proměnnou typu string nebo třída.
Př.: string, array, struct, class…
Dělení strukturovaných datových typů
Homogenní
Všechny hodnoty mají stejný datový typ
Př.: int[] – všechny položky v poli jsou typu int
Heterogenní
Hodnoty mají různé datové typy
Př.: struct nebo class – mohou obsahovat vlastnosti a členské proměnné, jejichž typy se mohou lišit např. int Age a string Name
Dle ukládání dat v paměti
Hodnotové datové typy
uloženy v paměti s názvem zásobník (stack)
velmi rychlý přístup a rychlé operace plynoucí z toho, že není nutná jakákoliv alokace/dealokace paměti
Referenční datové typy
uloženy v paměti s názvem halda (heap)
nutnost řešení alokací
Dle změnitelnosti hodnot
Mutable – hodnotu je možné kdykoliv změnit
Např.: int
Immutable – hodnotu není možné změnit
Toto omezení je hlídáno kompilátorem
Např.: string
Konverze datových typů
Konverze datových typů slouží k převodu jednoho datového typu na jiný.
Typy konverze
Konverzi lze dělit na dva typy:
Implicitní
Explicitní
Implicitní konverze
Dochází k ní automaticky bez nutnosti jakéhokoliv zásahu vývojáře
Podporována pouze ve chvíli, kdy nehrozí žádné problémy (např. podtečení, přetečení…)
Př.: Mějme proměnnouint x = 7; a provedeme přiřazení hodnoty do proměnné s datovým typem long long y = x;.
Do long je možné uložit jakýkoliv int, takže se provede automatická (implicitní) konverze na int na long
Explicitní
Vývojářem vynucená konverze
Tento typ není možné, aby kompilátor odhalil sám (např. z důvodu, že je přesný datový typ znám až za běhu programu – např. u polymorfismu)
Někdy je to také využíváno, když je potřebné obejít kontroly při kompilaci
Např.: Nechť je dána proměnná long x = 7; a je známo, že do ní program ukládá hodnoty v rozsahu {1, 2, .., 100}. Všechny tyto hodnoty lze uložit i do proměnné typu int, ale kompilátor bude hlásit chybu, že může dojít k podtečení. Pomocí explicitní konverze tuto konverzi vynutíme int y = (int) x;
Typy explicitní konverze:
(název_typu) – pokud se nepovede provést konverzi, tak vyhodí výjimku
Klíčové slovíčko as – pokud se nepovede provést konverzi, tak vrátí null
funguje pouze pro referenční nebo nullable typy
Pattern matching – pokud se konverze povede, tak je uložena hodnota do nové proměnné
object objInt = 42;object objStr = "123.45";// 1. Explicitní konverze pomocí ()int intValue = (int)objInt;Console.WriteLine($"(int) přetypování: {intValue}");// 2. Explicitní konverze pomocí 'as'string? strValue = objStr as string;if (strValue != null){ Console.WriteLine($"Přetypování pomocí 'as': {strValue}");}// 3. Pattern matching pomocí 'is'. Hodnota je pak uložena v proměnné s názvem 's'if (objStr is string s){ double parsed = double.Parse(s); Console.WriteLine($"Vzorové přiřazení a parsování na double: {parsed}");}
Přetečení a podtečení
Přetečení (overflow) a podtečení (underflow) jsou pojmy označující chyby v programu, které jsou způsobené překročením povoleného rozsahu hodnot datového typu.
Týká se to hlavně číselných hodnot
Přetečení ani podtečení při běhu nevyhazuje běžně výjimky, takže je důležité jim předcházet.
Checked blok slouží k detekci přetečení i podtečení. Pokud k některému z nich dojde, provede se vyhození výjimky OverflowException.
Opakem checked je unchecked, což je i výchozí nastavení běhového prostředí – tedy všechno je defaultně unchecked.
checked{ byte c = 255; c += 1; // vyhodí výjimku OverflowException}// alternativně:int d = checked(2147483647 + 1); // OverflowException
Klíčové slovo var
Jedná se o klíčové slovo pro implicitní typování. Znamená to, že kompilátor sám odvodí konkrétní datový typ proměnné podle hodnoty, kterou jí přiřadíš při deklaraci.
var cislo = 10; // kompilátor určí typ intvar jmeno = "Pepa"; // kompilátor určí typ stringvar seznam = new List<string>(); // kompilátor určí typ List<string>
Pravidla pro práci s var
Nutné přiřazení hodnoty při deklaraci – kompilátor musí hned vědět, jaký typ z toho má udělat.
Typ je pevně daný – po odvození už proměnnou nelze změnit na jiný typ.
Nelze jej použít jako návratový typ nebo typ parametru metody.
Kdy ho využít?
Když je typ zřejmý z pravé strany přiřazení: var pocet = 42;
Při práci s anonymními typy: var osoba = new { Jmeno = "Eva", Vek = 30 };
Při složitých typech: var slovnik = new Dictionary<string, List<int>>();
Kdy ho naopak nepoužít?
Pokud to snižuje čitelnost kódu – někdy je lepší uvést typ přímo, aby bylo jasné, co proměnná obsahuje.
// Jaký datový typ má result?var result = GetUserData();// Lepší možnost:UserData result = GetUserData();