9. Proměnná – přiřazovací příkaz, výraz

Programy pracují s daty a tato data potřebují uchovávat. Za tímto účelem využíváme proměnné (anglicky „Variable“), které lze vnímat jako pojmenovaný šuplík v paměti, do kterého program dočasně ukládá data. Pro její název platí stejná pravidla jako pro identifikátory. U názvu proměnných budeme psát malé počáteční písmeno. Název proměnné se používá k označení hodnoty, která je do ní uložena, a měl by dostatečně vystihovat podstatu proměnné, např. proměnná týkající se věku by měla být pojmenována jako vek a ne x39. Názvy proměnných by neměly být příliš dlouhé, nebo příliš krátké. Názvy proměnných by se neměly lišit pouze v počátečním písmenu, protože může dojít k jejich záměně např. MojePromenna vs mojePromenna.

Proměnná může obsahovat různé typy dat, které jsou do ní uloženy např. celá čísla, reálná čísla, Booleanovské logické hodnoty atd. Jedná se o tzv. datové typy (ty jsme již používaly ve vývojových diagramech našich algoritmů). Abychom mohly tyto šuplíky v paměti založit a popsat ji svým jménem a třeba ji i přiřadit nějakou počáteční hodnotu, je zapotřebí tzv. deklarovat proměnnou - viz Kód 1.

string osloveni;

Kód 1: Deklarace proměnné osloveni - program HelloWorldPromenna

Doplňme, jak vypadá značka deklarace proměnné osloveni ve vývojovém diagramu - viz Obrázek 1.

Deklarace proměnné osloveni - algoritmus HelloWorld_Promenna

Obrázek 1: Deklarace proměnné osloveni - algoritmus HelloWorld_Promenna

Pro uložení hodnoty do proměnné využíváme tzv. přiřazovací příkazu (operátor =). Jeho tvar je:

proměnná = výraz

kde:

  • proměnná - představuje identifikátor proměnné
  • = ... značí operátor přiřazení
  • výraz - představuje výraz jehož hodnota se přiřazuje. Výraz tvoří proměnné, konstanty, operátory, jména funkcí a závorky. Výraz reprezentuje pravidlo pro výpočet hodnot. Výraz se vyhodnocuje zleva doprava s ohledem na závorky a prioritu operátorů


Následující kód popisuje přiřazení pomocí operátoru (=), který představuje tzv. operátor přiřazení (anglicky „Assignment Operator“) - viz Kód 2. Každý krok (příkaz, výraz, atd.) je oddělen středníkem uváděným na konci.

//Přiřazení textu proměnné
osloveni = "Hello, World!";

Kód 2: Přiřazení hodnoty proměnné osloveni - program HelloWorldPromenna

Značka předchozího přiřazovacího příkazu ve vývojovém diagramu ve Flowgorithm vypadá následovně - viz Obrázek 2.

Obrázek 2: Přiřazení hodnoty proměnné osloveni - algoritmus HelloWorld_Promenna

Přiřazovat lze do proměnné, jejíž datový typ je datově kompatibilní vzhledem k přiřazení s datovým typem přiřazovaného výrazu. Předpokládejme, že na levé straně od přiřazovacího příkazu je proměnná datového typu TYP1 a na pravé straně přiřazovacího příkazu je výraz datového typu TYP2. Pak můžeme zjednodušeně, s ohledem na dosud vysvětlenou látku, tvrdit, že hodnota datového typu TYP2 je kompatibilní vzhledem k přiřazení s datovým typem TYP1, jestliže hodnoty datového typu TYP2 patří do množiny hodnot specifikované datovým typem TYP1. Jednoduše řečeno, pokud máte vpravo od přiřazovacího operátoru datový typ text, nemůže ho uložit do proměnné (na levé straně od operátoru přiřazení), která je celočíselného typu. V takovém případě musíte použít konverzi, která převede např. výraz na datový typ proměnné.

Hodnotu proměnné lze v C# nastavit i přímo v její deklaraci. Tomuto nastavení počáteční hodnoty se říká inicializace proměnné (anglicky „Initializing Variable") - viz Kód 3. 

//Deklarace proměnné včetně inicializace
string osloveni = "Hello, World!";

Kód 3: Inicializace proměnné osloveni - program HelloWorldPromenna

Nyní máme v proměnné uložený text. Abychom se k tomuto textu dostali (kouknuli se do  bloku paměti, kde je text uložen), stačí použít název proměnné (obecně lze říci identifikátor). Řekněme, že chceme k aktuální hodnotě uložené v proměnné, tedy "Hello, World!" připojit další text, např. " It is me, your PC.". V kódu se nejprve vyhodnotí pravá strana tzv. výrazu, tzn., že použitím názvu proměnné obdržíme její aktuální hodnotu, tj. "Hello, World!" a následně připojíme další text " It is me, your PC." pomocí operátoru +. Výraz se totiž vyhodnocuje zleva doprava za operátorem přiřazení (tj. =). Výsledná hodnota této textové operace (tj. "Hello, World! It is me, your PC.")  je následně uložena do proměnné uvedené na levé straně od operátoru =, tj. do proměnné osloveni - viz Kód 4.

//Připojení nového textu k obsahu proměnné a následné přiřazení do proměnné
osloveni = osloveni + " It is me, your PC.";

Kód 4: Připojení hodnoty k aktuálnímu obsahu proměnné osloveni - program HelloWorldPromenna

Ve vývojovém diagramu bychom k této operaci znovu využili značku pro přiřazení do proměnné.

Pokud bychom chtěli provést nějakou operaci např. výpisu obsahu proměnné, aniž by v ní byla uložena hodnota, nastal by chyba s výpisem "Use of unassigned local variable 'osloveni'". Jazyk C# nedovoluje používat proměnné, aniž by do ní nebyla přiřazena hodnota – pravidlo jednoznačného přiřazení (anglicky „Definite Assignment Rule“).

A jak by vypadaly všechny předchozí operace uplatněná na celá čísla?  Pojďme si nejprve ukázat, jak by vypadala deklarace celočíselné proměnné počet - viz Kód 5.

//Deklarace proměnné pro uložení celých čísel
int pocet;

Kód 5: Deklarace proměnné pocet

Při deklaraci lze hned provést inicializaci proměnné - viz Kód 6.

//Deklarace a inicializace celočíselné proměnné
int pocet = 0;

Kód 6: Inicializace proměnné pocet

Řekněme, že chceme k aktuální hodnotě uložené v proměnné pocet přičíst 1 - viz Kód 7.

//Operace přičtení 1 k aktuální hodnotě uložené v proměnné
pocet = pocet + 1;

Kód 7: Přičtení 1 k aktuální hodnotě v proměnné pocet

Pokud bychom chtěli provést nějakou početní operaci např. přičtení 1 do proměnné, aniž by v ní byla uložena hodnota, nastal by problém – pravidlo jednoznačného přiřazení - viz Kód 8.

//Deklarace proměnné pro uložení celých čísel
int pocet;
//Toto nelze provést, v proměnné není uložena hodnota
pocet = pocet + 1;

Kód 8: Příklad neplatného výrazu při absenci inicializace proměnné pocet

Pokud chceme inicializovat více proměnných najednou, můžete provést následující zápis – viz Kód 9. Asi si odvodíte, že tento výraz je vyhodnocován postupně zprava doleva.

//Deklarace více celočíselných proměnných
int pocet1, pocet2, pocet3;
//Inicializace více proměnných -> postupné vyhodnocení zprava doleva
pocet3 = pocet2 = pocet1 = 0;

Kód 9: Příklad inicializace více proměnných

V C# lze také zapsat následující kód - viz Kód 10. Tento kód ale znamená něco jiného než předchozí. V tomto kódu bude provedena pouze inicializace proměnné pocet3.

//Deklarace pouze jedné celočíselné proměnné ze tří proměnných
int pocet1, pocet2, pocet3 = 0;

Kód 10: Příklad inicializace pouze jedné proměnné ze tří proměnných


Obor platnosti

Proměnné mají také svůj obor platnosti:

  • Lokální proměnná – platná pouze pro část kódu
  • Třídní (nelokální) proměnná – lze použít v metodách třídy

Více o této problematice se dozvíme později, až budeme vysvětlovat metody.


Implicitně typované proměnná

U lokálních proměnných můžete také použít tzv. anonymní typ (přesněji se tomuto typu říká implicitně typovaná lokální proměnná – anglicky „Implicitly Typed Local Variable“), tzn., že nemusíme specifikovat datový typ proměnné (dosud jsme používali tzv. explicitně typované proměnné, kde jsme uváděli datový typ proměnné)  - viz Kód 11.

//Explicitně typovaná lokální proměnná
int explicitneTypovanaPromenna = 0;
//Implicitně typovaná lokální proměnná
var implicitneTypovanaPromenna = 0;

Kód 11: Příklad explicitně a implicitně typované lokální proměnné

Implicitní typ je odvozen kompilátorem při inicializace proměnné. Na ukázce zdrojového kódu vidíme, že si kompilátor odvodí dva různé datové typy – celé číslo a text – viz Kód 12.

//První implicitně typovaná lokální proměnná
var implicitneTypovanaPromenna1 = 0;
//Druhá implicitně typovaná lokální proměnná
var implicitneTypovanaPromenna2 = "text";

Kód 12: Příklad implicitně typované lokální proměnné

Pokud tedy neinicializujete tento typ proměnné, nelze s ní provádět další operace – viz Kód 13.

//Chybí inicializace implicitně typované proměnné
var implicitneTypovanaPromenna;
//Operaci přičtení nelze provést díky absenci inicializace
implicitneTypovanaPromenna = implicitneTypovanaPromenna + 1;

Kód 13: Příklad chyby u implicitně typované lokální proměnné