4. díl - Typový systém podruhé: Datové typy

Ostatní jazyky Visual Basic .NET Základní konstrukce Typový systém podruhé: Datové typy

V minulém dílu seriálu jsme si ukázali základní datové typy, byly to Integer, String a Single. Nyní se na datové typy podíváme více zblízka a vysvětlíme si, kdy jaký použít. Dnešní lekce bude hodně teoretická, ale o to více bude praktická ta příští. Na konci si vytvoříme pár jednoduchých ukázek.

VB.NET rozeznává dva druhy datových typů, hodnotové a referenční.

Hodnotové datové typy

Proměnné hodnotového datového typu si dokážeme jednoduše představit. Může se jednat např. o číslo nebo znak. V paměti je jednoduše uložena přímo hodnota a my k této hodnotě můžeme z programu přímo přistupovat. Slovo přímo jsem tolikrát nepoužil jen náhodou. V této sekci tutoriálů se budeme věnovat výhradně těmto proměnným.

Celočíselné datové typy

Podívejme se nyní na tabulku všech vestavěných celočíselných datových typů v .NET, všimněte si typu Integer, který již známe z minula.

Datový typ Rozsah Velikost .NET typ
SByte -128 až 127 8 bitů System.SByte
Byte 0 až 255 8 bitů System.Byte
Short -32 768 až 32 767 16 bitů System.Int16
UShort 0 až 65 535 16 bitů System.UInt16
Integer -2 147 483 648 až 2 147 483 647 32 bitů System.Int32
UInteger 0 až 4 294 967 295 32 bitů System.UInt32
Long -9 223 372 036 854 775 808 až 9 223 372 036 854 775 807 64 bitů System.Int64
ULong 0 až 18 446 744 073 709 551 615 64 bitů System.UInt64

Poznámka: všechna ta šílená čísla z tabulky si pamatovat nemusíte, téměř vždy vám pomůže ve Visual Studiu nástroj IntelliSense, který když budete psát ten datový typ a počkáte ukáže nad ním bublinu:

Případně v dokumentaci dodávané k Visual studiu to najdete podrobněji. Do dokumentace se dostanete, když napíšete konkrétní datový typ, označíte jej a stisknete F1.

Asi vás napadá otázka, proč máme tolik možných typů pro uložení čísla. Odpověď je prostá, záleží na jeho velikosti. Čím větší číslo, tím více spotřebuje paměti. Pro věk uživatele tedy zvolíme Byte, protože se jistě nedožije více, než 255 let. Představte si databázi milionu uživatelů nějakého systému, když zvolíme místo Byte Integer, bude zabírat 4x více místa. Naopak když budeme mít funkci k výpočtu faktoriálu, stěží nám bude stačit rozsah Integeru a použijeme Long.

Všimněte si, že některé typy začínají na U. Jsou téměř stejné, jako jejich dvojníci bez U, jen neumožňují záporné hodnoty a tím pádem na kladnou část mohou uložit 2x vyšší hodnotu. Těmto typům se říká unsigned, klasickým signed.

.NET typ je název dané struktury v .NET knihovnách. My používáme tzv. aliasy, aby byla práce jednodušší, ve skutečnosti si VB.NET kód:

Dim a As Integer = 10

přebere jako:

Dim a As System.Int32 = 10

My budeme samozřejmě používat aliasy, od toho tam jsou :)

Nad výběrem datového typu nemusíte moc přemýšlet a většinou se používá jednoduše Integer. Typ řešte pouze v případě, když jsou proměnné v nějakém poli (obecně kolekci) a je jich tedy více, potom se vyplatí zabývat se paměťovými nároky. Tabulky sem dávám spíše pro úplnost. Mezi typy samozřejmě funguje již zmíněná implicitní konverze, tedy můžeme přímo přiřadit Integer do proměnné typu Long a podobně, aniž bychom něco konvertovali.

Desetinná čísla

U desetinných čísel je situace poněkud jednodušší, máme na výběr pouze dva datové typy. Samozřejmě se liší opět v rozsahu hodnoty, dále však ještě v přesnosti (vlastně počtu des. míst). Double má již dle názvu dvojnásobnou přesnost oproti Single.

Datový typ Rozsah Přesnost .NET typ
Single +-1.5 * 10−45 až +-3.4 * 1038 7 čísel System.Single
Double +-5.0 * 10−324 až +-1.7 * 10308 15-16 čísel System.Double

Pozor, vzhledem k tomu, že desetinná čísla jsou v počítači uložena ve dvojkové soustavě, dochází k určité ztrátě přesnosti. Odchylka je sice téměř zanedbatelná, nicméně když budete programovat např. finanční systém, nepoužívejte tyto typy dat. typy pro uchování peněz, mohlo by dojít k malým odchylkám.

Když do Singlu chceme dosadit přímo ve zdrojovém kódu, musíme použít sufix F, u double sufix D (u double ho můžeme vypustit, jelikož je výchozí desetinný typ):

Dim a As Single = 3.14F
Dim b As Double = 2.72D

Jako desetinný separátor používáme ve zdrojovém kódu vždy tečku, nehledě na to, jaké máme ve Windows regionální nastavení.

Další vestavěné datové typy

Podívejme se na další datové typy, které nám .NET nabízí:

Datový typ Rozsah Velikost/Přesnost .NET typ
Char U+0000 až U+ffff 16 bitů System.Char
Decimal +-1.0 * 10−28 až +-7.9 * 1028 28-29 čísel System.Decimal
Boolean True nebo False 8 bitů System.Boolean

Char nám reprezentuje jeden znak, na rozdíl od Stringu, který reprezentoval celý řetězec charů. Znaky v VB.NET píšeme do uvozovek:

Dim c As Char = "A"

Char patří v podstatě do celočíselných proměnných (obsahuje číselný kód znaku), ale přišlo mi logičtější uvést ho zde. Char nám vrací např. metoda Console.ReadKey()

Decimal

Typ Decimal řeší problém ukládání desetinných čísel v binární podobě, ukládá totiž číslo vnitřně podobně, jako text. Používá se tedy pro uchování peněžních hodnot. Ke všem dalším matematickým operacím s des. čísly použijeme Single nebo Double. K zápisu Decimal hodnoty opět používáme sufix m:

Dim m As Decimal = 3.14159265358979323846m
Boolean

Boolean nabývá dvou hodnot: True (pravda) a False (nepravda). Budeme ho používat zejména tehdy, až se dostaneme k podmínkám. Do proměnné typu Boolean lze uložit jak přímo hodnotu True/False, tak i logický výraz. Zkusme si jednoduchý příklad:

Dim b As Boolean = False
Dim vyraz As Boolean = (15 > 5)
Console.WriteLine(b)
Console.WriteLine(vyraz)
Console.ReadKey()

Výstup programu:

False
True

Výrazy píšeme do závorek. Vidíme, že výraz nabývá hodnoty True (pravda), protože 15 je opravdu větší než 5. Od výrazů je to jen krok k podmínkám, na ně se podíváme příště.

Referenční datové typy

K referenčním typům se dostaneme až u objektově orientovaného programování, kde si také vysvětlíme zásadní rozdíly. Zatím budeme pracovat jen s tak jednoduchými typy, že rozdíl nepoznáme. Spokojíme se s tím, že referenční typy jsou složitější, než ty hodnotové. Jeden takový typ již známe, je jím String. Možná vás napadá, že String nemá nijak omezenou délku, je to tím, že s referenčními typy se v paměti pracuje jinak.

String má na sobě řadu opravdu užitečných metod. Některé si teď probereme a vyzkoušíme:

String

StartsWith, EndsWith a Contains

Můžeme se jednoduše zeptat, zda řetězec začíná, končí nebo zda obsahuje určitý podřetězec (substring). Podřetězcem myslíme část původního řetězce. Všechny tyto metody budou jako parametr brát samozřejmě podřetězec a vracet hodnoty typu Boolean (True/False). Zatím na výstup neumíme reagovat, ale pojďme si ho alespoň vypsat:

Dim s As String = "Krokonosohroch"
Console.WriteLine(s.StartsWith("krok"))
Console.WriteLine(s.EndsWith("hroch"))
Console.WriteLine(s.Contains("nos"))
Console.WriteLine(s.Contains("roh"))
Console.ReadKey()

Výstup programu:

False
True
True
False

Vidíme, že vše funguje podle očekávání. První výraz samozřejmě neprošel díky tomu, že řetězec ve skutečnosti začíná velkým písmenem.

ToUpper a ToLower

Rozlišování velkých a malých písmen může být někdy na obtíž. Mnohdy se budeme potřebovat zeptat na přítomnost podřetězce tak, aby nezáleželo na velikosti písmen. Situaci můžeme vyřešit pomocí metod ToUpper() a ToLower(), které vrací řetězec ve velkých a v malých písmenech. Uveďme si reálnější příklad než je Krokonosohroch. Budeme mít v proměnné řádek konfiguračního souboru, kterou psal uživatel. Jelikož se na vstupy od uživatelů nelze spolehnout, musíme se snažit eliminovat možné chyby, zde např. s velkými písmeny.

Dim konfig As String = "Fullscreen shaDows autosave"
konfig = konfig.ToLower()
Console.WriteLine("Poběží hra ve fullscreenu?")
Console.WriteLine(konfig.Contains("fullscreen"))
Console.WriteLine("Budou zapnuté stíny?")
Console.WriteLine(konfig.Contains("shadows"))
Console.WriteLine("Přeje si hráč vypnout zvuk?")
Console.WriteLine(konfig.Contains("nosound"))
Console.WriteLine("Přeje si hráč hru automaticky ukládat?")
Console.WriteLine(konfig.Contains("autosave"))
Console.ReadKey()

Výstup programu:

Poběží hra ve fullscreenu?
True
Budou zapnuté stíny?
True
Přeje si hráč vypnout zvuk?
False
Přeje si hráč hru automaticky ukládat?
True

Vidíme, že jsme schopni zjistit přítomnost jednotlivých slov v řetězci tak, že si nejprve řetězec převedeme celý na malá písmena (nebo na velká) a potom kontrolujeme přítomnost slova jen malými (nebo velkými) písmeny. Takhle by mimochodem mohlo opravdu vypadat jednoduché zpracování nějakého konfiguračního skriptu.

Trim, TrimStart a StrimEnd

Problémem ve vstupech od uživatele může být i diakritika, ale VB.NET naštěstí pracuje plně v UTF8, nestane se nám tedy, že by se diakritika nějak zkomolila. Další nástrahou mohou být mezery a obecně všechny tzv. bílé znaky, které nejsou vidět, ale mohou nám uškodit. Obecně může být dobré trimovat všechny vstupy od uživatele, můžeme trimovat buď celý řetězec nebo jen bílé znaky před ním a za ním. Prozradím, že při parsovacích funkcích VB.NET trimuje zadaný řetězec automaticky, než s ním začne pracovat. Zkuste si v následující aplikaci před číslo a za číslo zadat několik mezer:

Console.WriteLine("Zadejte číslo:")
Dim s As String = Console.ReadLine()
Console.WriteLine("Zadal jste text: " & s)
Console.WriteLine("Text po funkci trim: " & s.Trim())
Dim a As Integer = CInt(s)
Console.WriteLine("Převedl jsem zadaný text na číslo parsováním, zadal jste: " & a)
Console.ReadKey()
Replace

Asi nejdůležitější metodou na Stringu je nahrazení určité jeho části jiným textem. Jako parametry zadáme dva podřetězce, jeden co chceme nahrazovat a druhý ten, kterým to chceme nahradit. Metoda vrátí nový String, ve kterém proběhlo nahrazení. Když daný podřetězec metoda nenajde, vrátí původní řetězec. Zkusme si to:

Dim s As String = "C# je nejlepší!"
s = s.Replace("C#", "VB.NET")
Console.Write(s)
Console.ReadKey()

Výstup programu:

VB.NET je nejlepší!
Format

Format je velmi užitečná metoda, která nám umožňuje vkládat do samotného textového řetězce zástupné značky. Ty jsou reprezentovány jako číslo ve složených závorkách, prvním číslem je 0. Jako další parametry metody následují v tomto pořadí proměnné, které se mají do textu místo značek vložit. Všimněte si, že se metoda nevolá na konkrétní proměnné (přesněji instanci, viz další díly), ale přímo na typu String.

Dim a As Integer = 10
Dim b As Integer = 20
Dim c As Integer = a + b
Dim s As String = String.Format("Když sečteme {0} a {1}, dostaneme {2}", a, b, c)
Console.WriteLine(s)
Console.ReadKey()

Výstup programu:

Když sečteme 10 a 20, dostaneme 30

Konzole sama umí přijímat text v takovémto formátu, můžeme tedy napsat:

Dim a As Integer = 10
Dim b As Integer = 20
Dim c As Integer = a + b
Console.WriteLine("Když sečteme {0} a {1}, dostaneme {2}", a, b, c)
Console.ReadKey()

Toto je velmi užitečná a přehledná cesta, jak sestavovat řetězce, a určitě se ji vyplatí mnohdy použít místo běžné konkatenace pomocí operátoru "&", pokud nebazírujeme na vysoké rychlosti.

PadLeft a PadRight

Jako poslední si zmíníme metody, které nám k textu naopak mezery přidají :) K čemu to je dobré? Představte si, že máme 100 proměnných a budeme je chtít seřadit do tabulky. Text upravíme pomocí metody PadRight() s parametrem šířky sloupce, tedy např. 20 znaků. Pokud bude mít text jen 12 znaků, vypíše se před něj 8 mezer, aby měl velikost 20. Obdobně metoda PadLeft() by vypsala 8 mezer za něj. Jelikož nemáme znalosti k vytvoření takové tabulky, budeme si metody jen pamatovat a vyzkoušíme si je jindy, až budeme programovat kalendář.

Vlastnost Length

Poslední, ale nejdůležitější vlastnost (pozor, ne metoda) je Length, tedy délka. Vrací celé číslo, které představuje počet znaků v řetězci. Za vlastnosti nepíšeme závorky, protože nemají parametry.

Console.WriteLine("Zadejte vaše jméno")
Dim jmeno As String = Console.ReadLine()
Dim delkaJmena As Integer = jmeno.Length
Console.WriteLine("Délka vašeho jména je: " & delkaJmena)
Console.ReadKey()

Je toho ještě spoustu k vysvětlování a jsou další datové typy, které jsme neprobrali. Aby jsme však stále neprobírali jen teorii, ukážeme si již příště podmínky a cykly, potom bude naše programátorská výbava dostatečně velká k tomu, abychom tvořili zajímavé programy :)


 

  Aktivity (3)

Článek pro vás napsal Michal Žůrek (misaz)
Avatar
Autor se věnuje tvorbě aplikací pro počítače, mobilní telefony, mikroprocesory a tvorbě webových stránek a webových aplikací. Nejraději programuje ve Visual Basicu a TypeScript. Ovládá HTML, CSS, JavaScript, TypeScript, C# a Visual Basic.

Jak se ti líbí článek?
Celkem (5 hlasů) :
55555


 


Miniatura
Předchozí článek
Cvičení k 3. lekci VB.NET
Miniatura
Následující článek
Cvičení k 4. lekci VB.NET

 

 

Komentáře

Avatar
Ben Žour (Jeremy):

Mě se ten VB .NET líbí čím dál víc! :) V některých věcech mi přijde občas i lepší než C#, ikdyž delší kód v něm je na první pohled lehce chaotický. Každopádně díky za psaní článků!

 
Odpovědět 23.4.2013 22:56
Avatar
Odpovídá na Ben Žour (Jeremy)
Michal Žůrek (misaz):

Počkej až si najdu čas napsat článek "Co ti síšarpáři nemají" :)

Ony ty jazyky jsou celkem stejné až na syntaxi, která se mírně liší. Kód VB.NET si myslím je stejně dlouhý jako C#, protože:
VB.NET:

Dim ctecka = New IO.StreamReader(...)

C#:

IO.StreamReader ctecka = New IO.StreamReader(...)

Nicméně kvůli klíčových slov je něco o tochu delší.

Jinak ty jazyky jsou úplně stejné.

Odpovědět 24.4.2013 6:33
Nesnáším {}, proto se jim vyhýbám.
Avatar
Odpovídá na Michal Žůrek (misaz)
Luboš Běhounek (Satik):
IO.StreamReader ctecka = New IO.StreamReader(...)

muzes zapsat jako

var ctecka = New IO.StreamReader(...)

pak je to dlouhe stejne :) .

Odpovědět 24.4.2013 8:54
:)
Avatar
Kit
Redaktor
Avatar
Odpovídá na Luboš Běhounek (Satik)
Kit:

V Javě také můžeš napsat třeba

Object str = "řetězec";

Jenom není vhodné to používat systematicky, ale jen tam, kde to skutečně potřebuji, protože tím trpí přehlednost kódu.

Takže var ano, ale jen tam, kde je to nutné.

Odpovědět 24.4.2013 12:05
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Michael Olšavský:

Pěkné články. Jen tak dál ;-) Nikdy jsem neměl rád VB syntaxi, ale jak vidím, není to tak špatné. A díky .NET je to hodně podobné C#.

 
Odpovědět 25.4.2013 16:05
Avatar
Odpovídá na Michael Olšavský
Michal Žůrek (misaz):

Až na tu santyxi je to víceméně stejné.

Odpovědět 25.4.2013 16:24
Nesnáším {}, proto se jim vyhýbám.
Avatar
Kit
Redaktor
Avatar
Odpovídá na Michal Žůrek (misaz)
Kit:

Dnešní programovací jazyky se snaží navázat na ty předchozí, aby uživatelé nemuseli moc měnit své návyky, ale aby jim byly nabídnuty nové vlastnosti.

Zcela odlišný jazyk se dělá pouze pokud se vytváří nové paradigma.

Odpovědět  +1 25.4.2013 16:51
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Libor Šimo (libcosenior):

Misaz, v časti: Trim, TrimStart a StrimEnd máš v códe chybu.

Console.WriteLine("Zadejte číslo:")
Dim s As String = Console.ReadLine()
Console.WriteLine("Zadal jste text: " + s)
Console.WriteLine("Text po funkci trim: " + s.Trim())
Dim a As Integer = CInt(s)
Console.WriteLine("Převedl jsem zadaný text na číslo parsováním, zadal jste: " & a)
Console.ReadKey()

Ďalek som si všimol že pri výpise sa dá použiť operátor + vtedy, keď sa jedná o vypísanie stringu, pri číslach musí byť &.
Nemýlim sa?

Odpovědět 14.7.2013 20:10
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
Odpovídá na Libor Šimo (libcosenior)
Michal Žůrek (misaz):

Aha dík.

  • by mělo sloužit pro sčítání a string je pole, ty měly jít sčítat, proto jde i string sčítat.

& slouží pro spojování:

5 & 5 = 55
5 + 5 = 10
Odpovědět  +1 14.7.2013 20:33
Nesnáším {}, proto se jim vyhýbám.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 9 zpráv z 9.