Pouze tento týden sleva až 80 % na e-learning týkající se Javy. A zároveň využij akce až 30 % zdarma při nákupu e-learningu - Více informací.
Hledáme koordinátorku kurzů a programátora, 100% home office, 100% flexibilní. Prozkoumej aktuální pozice
Java week

Lekce 3 - Proměnné, typový systém a parsování v C# .NET

Z minulé lekce C# kurzu, Visual Studio a první konzolová aplikace v C# .NET, již umíme pracovat s Visual Studiem a vytvořit konzolovou aplikaci.

Dnes se v tutoriálu podíváme na tzv. typový systém, ukážeme si základní datové typy a práci s proměnnými. Výsledkem budou 4 jednoduché programy včetně kalkulačky.

Proměnné

Než začneme řešit datové typy, pojďme se shodnout na tom, co je to proměnná (programátoři mi teď jistě odpustí zbytečné vysvětlování). Určitě znáte z matematiky proměnnou (např. x), do které jsme si mohli uložit nějakou hodnotu, nejčastěji číslo. Proměnná je v informatice naprosto to samé, je to místo v paměti počítače, kam si můžeme uložit nějaká data (jméno uživatele, aktuální čas nebo databázi článků). Toto místo má podle typu proměnné také vyhrazenou určitou velikost, kterou proměnná nesmí přesáhnout (např. číslo nesmí být větší než 2 147 483 647).

Proměnná má vždy nějaký datový typ, může to být číslo, znak, text a podobně, záleží na tom, k čemu ji chceme používat. Většinou musíme před prací s proměnnou tuto proměnnou nejdříve tzv. deklarovat, čili říci jazyku jak se bude jmenovat a jakého datového typu bude (jaký v ní bude obsah). Jazyk ji v paměti založí a teprve potom s ní můžeme pracovat. Podle datového typu proměnné si ji jazyk dokáže z paměti načíst, modifikovat, případně ji v paměti založit. O každém datovém typu jazyk ví, kolik v paměti zabírá místa a jak s tímto kusem paměti pracovat.

Typový systém

Existují dva základní typové systémy: statický a dynamický.

  • Dynamický typový systém nás plně odstiňuje od toho, že proměnná má vůbec nějaký datový typ. Ona ho samozřejmě vnitřně má, ale jazyk to nedává najevo. Dynamické typování jde mnohdy tak daleko, že proměnné nemusíme ani deklarovat, jakmile do nějaké proměnné něco uložíme a jazyk zjistí, že nebyla nikdy deklarována, sám ji založí. Do té samé proměnné můžeme ukládat text, potom objekt uživatele a potom desetinné číslo. Jazyk se s tím sám popere a vnitřně automaticky mění datový typ. V těchto jazycích jde vývoj rychleji díky menšímu množství kódu, zástupci jsou např. PHP nebo Ruby.
  • Statický typový systém naopak striktně vyžaduje definovat typ proměnné a tento typ je dále neměnný. Jakmile proměnnou jednou deklarujeme, není možné její datový typ změnit. Jakmile se do textového řetězce pokusíme uložit objekt uživatel, dostaneme vynadáno.

C# je staticky typovaný jazyk, všechny proměnné musíme nejprve deklarovat s jejich datovým typem. Nevýhodou je, že díky deklaracím je zdrojový kód poněkud objemnější a vývoj pomalejší. Obrovskou výhodou však je, že nám kompiler před spuštěním zkontroluje, zda všechny datové typy sedí. Dynamické typování sice vypadá jako výhodné, ale zdrojový kód není možné automaticky kontrolovat a když někde očekáváme objekt uživatel a přijde nám tam místo toho desetinné číslo, odhalí se chyba až za běhu a interpret program shodí. Naopak C# nám nedovolí program ani zkompilovat a na chybu nás upozorní (to je další výhoda kompilace).

Pojďme si nyní něco naprogramovat, ať si nabyté znalosti trochu osvojíme, s teorií budeme pokračovat až příště. Řekněme si nyní tři základní datové typy:

  • Celá čísla: int
  • Desetinná čísla: float
  • Textový řetězec: string

Program vypisující proměnnou

Zkusíme si nadeklarovat celočíselnou proměnnou a, dosadit do ní číslo 56 a její obsah vypsat do konzole. Založte si nový projekt, pojmenujte ho Vypis (i ke všem dalším příkladům si vždy založte nový projekt). Kód samozřejmě píšeme do těla metody Main() (jako minule), čili ji zde již nebudu opisovat.

int a;
a = 56;
Console.WriteLine(a);
Console.ReadKey();

První příkaz nám nadeklaruje novou proměnnou a datového typu int. Proměnná tedy bude sloužit pro ukládání celých čísel. Druhý příkaz provádí přiřazení do proměnné, slouží k tomu operátor "rovná se" (=). Poslední příkaz je nám známý, vypíše do konzole obsah proměnné a. Konzole je chytrá a umí vypsat i číselné proměnné. ReadKey() je nám známý.

Konzolová aplikace
56

Pro desetinnou proměnnou by kód vypadal takto:

float a;
a = 56.6F;
Console.WriteLine(a);
Console.ReadKey();
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Je to téměř stejné jako s celočíselným. Jako desetinný oddělovač používáme tečku (.) a na konci desetinného čísla je nutné zadat tzv. suffix F, tím říkáme, že se jedná o float.

Program Papoušek

Minulý program byl poněkud nudný, zkusme nějak reagovat na vstup od uživatele. Napíšeme program papoušek, který bude dvakrát opakovat to, co uživatel napsal. Ještě jsme nezkoušeli z konzole nic načítat, ale je to velmi jednoduché. Slouží k tomu metoda ReadLine(), která nám vrátí textový řetězec z konzole. Zkusme si napsat následující kód:

Console.WriteLine("Ahoj, jsem virtuální papoušek Lóra, rád opakuji!");
Console.WriteLine("Napiš něco: ");

string vstup;
vstup = Console.ReadLine();

string vystup;
vystup = vstup + ", " + vstup + "!";

Console.WriteLine(vystup);
Console.ReadKey();

To už je trochu zábavnější :) První dva řádky jsou jasné, dále deklarujeme textový řetězec vstup. Do vstup se přiřadí hodnota z metody ReadLine() na konzoli, tedy to, co uživatel zadal. Pro výstup si pro názornost zakládáme další proměnnou typu textový řetězec. Zajímavé je, jak do vystup přiřadíme, tam využíváme tzv. konkatenace (spojování) řetězců. Pomocí operátoru + totiž můžeme spojit několik textových řetězců do jednoho a je jedno, jestli je řetězec v proměnné nebo je explicitně zadán v uvozovkách ve zdroj. kódu. Do proměnné tedy přiřadíme vstup, dále čárku, znovu vstup a poté vykřičník. Proměnnou vypíšeme, vyčkáme na stisk klávesy a skončíme.

Konzolová aplikace
Ahoj, jsem virtuální papoušek Lóra, rád opakuji!
Napiš něco:
Nazdar ptáku
Nazdar ptáku, Nazdar ptáku!

Do proměnné můžeme přiřazovat již v její deklaraci, můžeme tedy nahradit:

string vstup;
vstup = Console.ReadLine();

za

string vstup = Console.ReadLine();

Program by šel zkrátit ještě více v mnoha ohledech. Obecně je ale lepší používat více proměnných a dodržovat přehlednost, než psát co nejkratší kód a po měsíci zapomenout, jak vůbec funguje.

Program zdvojnásobovač

Zdvojnásobovač si vyžádá na vstupu číslo a to poté zdvojnásobí a vypíše. Asi bychom s dosavadními znalostmi napsali něco takového:

Console.WriteLine("Zadejte číslo k zdvojnásobení:");
int a = Console.ReadLine();
a = a * 2;
Console.WriteLine(a);
Console.ReadKey();

Všimněte si zdvojnásobení čísla a, které jsme provedli pomocí přiřazení. C# nám nyní vyhubuje a podtrhne řádek, ve kterém se snažíme hodnotu z konzole dostat do proměnné typu int. Narážíme na typovou kontrolu, konkrétně nám ReadLine() vrací string a my se ho snažíme uložit do intu. Cokoli přijde z textové konzole je vždy text a to i když zadáme číslo. Budeme ho potřebovat tzv. naparsovat.

Parsování

Parsováním se myslí převod z textové podoby na nějaký specifický typ, např. číslo. Mnoho datových typů má v C# již připraveny metody k parsování, pokud budeme chtít naparsovat např. int ze stringu, budeme postupovat takto:

string s = "56";
int a = int.Parse(s);

Vidíme, že datový typ int má na sobě přímo metodu Parse(), která bere jako parametr textový řetězec a vrátí číslo. Využijeme této znalosti v našem programu:

Console.WriteLine("Zadejte číslo k zdvojnásobení:");
string s = Console.ReadLine();
int a = int.Parse(s);
a = a * 2;
Console.WriteLine(a);
Console.ReadKey();

Nejprve si text z konzole uložíme do textového řetězce s. Do celočíselné proměnné a poté uložíme číselnou hodnotu řetězce s. Dále hodnotu v a zdvojnásobíme a vypíšeme do konzole.

Konzolová aplikace
Zadejte číslo k zdvojnásobení:
1024
2048

Můžete se setkat s parsováním ze stringu pomocí třídy Convert, ta však slouží ke konverzi mezi čísly a s textem si nemusí správně poradit, je to tedy špatné řešení.

Parsování se samozřejmě nemusí povést, když bude v textu místo čísla např. "slovo", ale tento případ zatím nebudeme ošetřovat.

Jednoduchá kalkulačka

Ještě jsme nepracovali s desetinnými čísly, zkusme si napsat slibovanou kalkulačku. Bude velmi jednoduchá, na vstup přijdou dvě čísla, program poté vypíše výsledky pro sčítání, odčítání, násobení a dělení.

Console.WriteLine("Vítejte v kalkulačce");
Console.WriteLine("Zadejte první číslo:");
float a = float.Parse(Console.ReadLine());
Console.WriteLine("Zadejte druhé číslo:");
float b = float.Parse(Console.ReadLine());
float soucet = a + b;
float rozdil = a - b;
float soucin = a * b;
float podil = a / b;
Console.WriteLine("Součet: " + soucet);
Console.WriteLine("Rozdíl: " + rozdil);
Console.WriteLine("Součin: " + soucin);
Console.WriteLine("Podíl: " + podil);
Console.WriteLine("Děkuji za použití kalkulačky, aplikaci ukončíte libovolnou klávesou.");
Console.ReadKey();

Konzolová aplikace
Vítejte v kalkulačce
Zadejte první číslo:
3,14
Zadejte druhé číslo:
2,72
Součet: 5,86
Rozdíl: 0,42
Součin: 8,5408
Podíl: 1,15441176470588
Děkuji za použití kalkulačky, aplikaci ukončíte libovolnou klávesou.

Všimněte si dvou věcí. Zaprvé jsme zjednodušili parsování z konzole tak, abychom nepotřebovali stringovou proměnnou, protože bychom ji stejně již poté nepoužili. Zadruhé na konci programu spojujeme řetězec s číslem pomocí operátoru +. C# překvapivě nezahlásí chybu, ale provede tzv. implicitní konverzi a zavolá na čísle metodu ToString(). Kdyby tomu tak nebylo nebo jsme se dostali do situace, kdy potřebujeme převést cokoli na string, zavoláme na proměnné metodu ToString(). C# to v tomto případě udělal za nás, v podstatě vykoná:

Console.WriteLine("Součet: " + soucet.ToString());

Právě jsme se tedy naučili opak k parsování - převést cokoli do textové podoby.

Operátor nameof

Někdy se nám může hodit získat místo hodnoty proměnné její název. Slouží k tomu operátor nameof:

int cislo = 5;
Console.WriteLine(nameof(cislo));

Výstup:

Konzolová aplikace
cislo

Můžeme si vyzkoušet, že program opravdu nevypíše pětku, ale cislo.

Všechny programy máte samozřejmě opět v příloze, zkoušejte si vytvářet nějaké podobné, znalosti již k tomu máte :)

V následujícím cvičení, Řešené úlohy k 1.-3. lekci C# .NET, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 2153x (87.57 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

Předchozí článek
Visual Studio a první konzolová aplikace v C# .NET
Všechny články v sekci
Základní konstrukce jazyka C# .NET
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 1.-3. lekci C# .NET
Článek pro vás napsal David Čápka
Avatar
Uživatelské hodnocení:
302 hlasů
David je zakladatelem ITnetwork a programování se profesionálně věnuje 13 let. Má rád Nirvanu, sushi a svobodu podnikání.
Unicorn university David se informační technologie naučil na Unicorn University - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity

 

 

Komentáře
Zobrazit starší komentáře (189)

Avatar
Zdeněk Novák:23.5.2021 20:32

Ahoj, ve VS 2019 mi bohužel instrukce "nameof" nefunguje. Zkoušel jsem i převzít program odsud, ale výsledek je stejný. Nesetkal se s tím někdo také? Díky.

 
Odpovědět
23.5.2021 20:32
Avatar
Alesh
Překladatel
Avatar
Odpovídá na Zdeněk Novák
Alesh:23.5.2021 23:16

Tak předně je lepší používat angličtinu ve VS, ten překlad toho erroru je takový docela na ... , v angličtině to je pochopitelné podle mě hned, v čem je problém:

Error CS0118 'nameof' is a namespace but is used like a variable nameof

 
Odpovědět
23.5.2021 23:16
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Alesh
DarkCoder:24.5.2021 15:56

Ano, používat vývojové prostředí v jazyce jiném než v angličtině je pro masochisty. Že překlad dokumentace je jak výstup z Google translátoru je známá věc. Dále dost věcí pro snazší ovládání je jazykově závislých.

Bohužel to není jediná hrůza která programátora může potkat. Debugger je další příklad, nad jehož výstupem lze kroutit hlavou.

Což o to, on ten překlad chybové hlášky je korektní ve smyslu překladu do českého jazyka, ale bohužel naprosto nevypovídající o příčině chyby a to i v angličtině. Vzít identifikátor, zjistit jeho význam, porovnat ho v sekci s tím co se očekává a informovat o tom programátora je dosti nedostačující. V tomto případě je debugger až za tupce, když nerozpozná že obor názvů / jmenný prostor úzce souvisí s proměnnou a že celý problém spočívá v nesprávné syntaxi, kde identifikátor jmenného prostoru předchází identifikátoru proměnné oddělenými mezi sebou tečkou.

Ale proč by nám byla usnadňována práce, že. :-)

Odpovědět
24.5.2021 15:56
"„Učíš-li se proto, aby sis zapamatoval, zapomeneš. Učíš-li se proto, abys porozuměl, zapamatuješ si."
Avatar
Katka Mlázovská:2.7.2021 19:25

Tak jsem synátora poučovala, že:

Jakmile proměnnou jednou deklarujeme, není možné její datový typ změnit.

A protože to je typický, vzdorovitý pubescent, byla jeho odpověď:

string a = "123";
Console.WriteLine(Convert.ToInt32(a).GetType());
//System.Int32
:-D
Odpovědět
2.7.2021 19:25
easy choices => hard life; hard choices => easy life;
Avatar
Josef Behenský :17.8.2021 10:06

AHoj, vžycky jak je kod tak ten starý mám smazat ne:

 
Odpovědět
17.8.2021 10:06
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Ivo Lhotský
Člen
Avatar
Ivo Lhotský:18.11.2021 20:05

"Nechápu" smysl operátoru nameof .
K čemu je mi dotaz na název proměnné, když se ptám jejím názvem?
Jak se jmenuje Petr? Jmenuje se Petr. Proč psát (nameof(cislo) a ne "číslo".
Může mi někdo naznačit, kde by se to dalo využít?

 
Odpovědět
18.11.2021 20:05
Avatar
Josef Prokeš:26.11.2021 20:23

Pořád mi chybí popis těla programu ve složených uvozovkách. Doteď jsem programoval ve VB VS a tam přesně vím, co jak má hlavička programu vypadat, k čemu co je a jak to přesně funguje.

 
Odpovědět
26.11.2021 20:23
Avatar
Květa S
Člen
Avatar
Odpovídá na Zdeněk Novák
Květa S:10.12.2021 8:37

Ahoj, měla jsem tentýž problém. Pro začátečníka frustrující.
Ono totiž o kus výše, kde my nic nepíšeme, ani si toho nemáme všímat, je namespace nameof. Máme nameof nahoře a pak nameof dole, a proto hlásí error. Připsala jsem nahoru f navíc, nyní tam mám namespace nameoff, a už neprotestuje.

 
Odpovědět
10.12.2021 8:37
Avatar
Ladislav SKOKAN:29.12.2021 16:12

U parsování bych v základu doporučil řešit také chybu pro případ, že znak není číslo. Třeba testem, zda je znak vůbec číslo, kdy můžeme okamžitě reagovat opakovaným zadáním anebo rovnou získat číslo.
Využití funkce nameof se zcela vymyká logice.

 
Odpovědět
29.12.2021 16:12
Avatar
Pavel Štěrba:12. ledna 21:06

překvapivě mi nefungovalo
float a = float.Parse(Con­sole.ReadLine());
musel jsem nahradit
string sa;
sa = Console.ReadLine();
float a = float.Parse(sa);

 
Odpovědět
12. ledna 21:06
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 10 zpráv z 199. Zobrazit vše