6. srpna 2015 16:16

4. díl - Čtení ze vstupu

Dnes si povíme o dalších operátorech, které nám zjednoduší operace, které již umíme. Dále si ukážeme, jak přečíst hodnotu proměnné ze vstupu od uživatele a napíšeme si náš první interaktivní program.

Jednodušší změna hodnoty proměnné

Často ve vašich programech budete potřebovat změnit hodnotu nějaké proměnné podle původní hodnoty - např. budete chtít hodnotu proměnné zvýšit o 10. Pokud dáte dohromady to, co už umíme, mohli byste to napsat tímto příkazem:

cislo = cislo + 10;

Pokud byla hodnota proměnné cislo 3, nová bude 13, pokud byla 7, nová bude 17, pokud byla 934, nová bude 944.

Všimněte si, že v tomto příkazu jsme na tak jednoduchý úkon museli dvakrát psát název jedné proměnné. Na toto v jazyce C++ existuje řešení a tím je operátor += (nejedná se o dva operátory, ale o jeden!). Tento operátor je velmi podobný přiřazovacímu operátoru =, ale nepřiřazuje hodnotu výrazu napravo, ale nejdříve tento výraz sečte s aktuální hodnotou proměnné a až potom tuto hodnotu přičte zpět do proměnné. Operace se vyhodnotí jako hodnota proměnné po přiřazení stejně jako u přiřazovacího operátoru. Celý příkaz vypadá takto:

cislo += 10;

Tento tvar mají i všechny ostatní početní operátory, které jsme se učili: -=, *=, /= a %=. Všechny tyto operátory mají stejnou prioritu, jako přiřazovací operátor. Když tedy máte takovýto příkaz:

cislo *= 2 + 3;

Provede se nejdřív sčítání a až potom násobení a přiřazení, protože operátor přiřazení má nižší prioritu, než operátor sčítání. Pro lepší představu si tento příkaz můžete představit se závorkami:

cislo *= (2 + 3);

A kdybychom to rozepsali na dlouhý tvar, vypadalo by to takto:

cislo = cislo * (2 + 3);

Funkčnost má úplně stejnou jako předchozí příkaz.

Inkrementace a dekrementace

Ještě častěji budeme chtít hodnotu proměnné zvýšit, nebo snížit pouze o jedničku. To bychom mohli napsat takto:

cislo += 1;

Jazyk C++ ale dovoluje ještě jednodušší zápis a to pomocí unárního operátoru inkrementace ++. Příkaz vypadá takto:

++cislo;

Tento příkaz funguje stejně jako předchozí. Vezme hodnotu proměnné, přičte k ní jedničku a pak ji zpět do proměnné uloží. Operace se opět vyhodnotí jako výsledná hodnota uložená v proměnné.

C++ samozřejmě nabízí i opačný operátor dekrementace --, který jedničku odečítá.

Prefix a postfix

Operátory inkrementace a dekrementace mají dvě podoby: prefixový (předponový) a postfixový (příponový) tvar. My jsme si zatím ukázali prefixový tvar - operátor jsme napsali před proměnnou. Postfixový tvar se píše za proměnnou:

cislo++;

Oba tvary dělají to samé - přičítají jedničku (nebo v případě dekrementace odečítají). Prefixový tvar se vyhodnotí jako výsledná hodnota proměnné, ale postfixový jako původní hodnota proměnné. Jinými slovy pokud máte ++cislo, nejdříve se provede inkrementace a pak se operace vyhodnotí jako hodnota proměnné. Ale pokud máte cislo++, nejdříve se vyhodnotí operace jako hodnota proměnné a až potom se inkrementuje hodnota.

Pozor na pořadí zpracování!

Co se stane, pokud napíšete následující příkazy:

int a = 3, b;
b = a-- + a++;

Očekávání: nejdříve se provede a--, tedy dekrementace se vyhodnotí jako hodnota 3 a proměnná a se sníží o jedničku. Potom se provede a++ - výraz se vyhodnotí jako 2 a proměnná a se opět zvýší o jedna. Na konec se čísla 3 a 2 sečtou a do proměnné b se uloží 5.

Možná to zní logicky a může to být i pravda. Ale pozor, nemusí! Kompilátor GCC mi zobrazil varování, že operace nad proměnnou a může být nedefinována (nedefinované chování = může to dopadnou jakkoli), program se ale přeložil a v proměnné b se opravdu objevila hodnota 5. Kompilátor VC++ nezobrazil žádné varování, ale v proměnné b se objevilo číslo 6!

Problém je postfixový tvar inkrementace a dekrementace. Protože nejdříve se výraz vyhodnotí a až potom proběhne změna hodnoty proměnné. Otázka ale je, kdy přesně je potom? Standard jazyka C++ říká, že hodnota se má změnit po provedení výrazu. Už ale nedefinuje, kterého - nechává to na kompilátoru. V případě dekrementace v našem výrazu jsou tři možnosti:

  1. Po výrazu a--.
  2. Po výrazu a-- + a++.
  3. Po výrazu b = a-- + a++.

Dokonce dekrementace může nastat až po inkrementaci, protože standard nedefinuje, jestli se u operátoru + vyhodnotí nejdříve levý operand nebo pravý. Stejně to platí i u všech dalších operátorů (pokud pořadí nedefinuje priorita nebo asociace - což v tomto případě tak není a nepomohou nám ani závorky).

Na tento problém existuje jednoduché řešení: stačí si pamatovat, že nesmíte měnit obsah jedné proměnné v jednom příkazu více, než jednou!

Čtení ze vstupu

Čtení ze vstupu je stejně jednoduché, jako tisk na výstup. Ke čtení slouží proměnná cin (čti sí-in). Název je z anglického character input (znakový vstup). Obsah proměnné ze vstupu načteme obdobně, jako u tisku:

int cislo;
cin >> cislo;

Všimněte si, že operátor směřuje na druhou stranu, než jak je tomu u tisku. Směr si můžete pamatovat podle toho, kterým směrem putují data: u tisku putují z proměnné na výstup a u čtení ze vstupu do proměnné.

Pamatujte, že proměnné cin i cout musí být vždy nalevo, nelze je prohodit!

Když program spustíte, zobrazí se blikající textový kurzor a program čeká, až zadáte číslo. Číslo odešlete stiskem klávesy enter.

Čtení ze vstupu lze řetězit stejně jako tisk. Viz:

int a, b;
cin >> a >> b;
cout << "Zadali jste cisla " << a << " a " << b << ".";

Při zadávání čísel musíte každé zvlášť potvrdit enterem, nebo mezi ně napsat mezeru (všechny bílé znaky - mezery, tabulátory a konce řádků se ignorují) a potvrdit je najednou. Nelze je oddělit žádným jiným znakem, např. čárkou! Toto uživatel pravděpodobně neví, a tak je lepší se zeptat na každé číslo zvlášť:

int sirka, vyska;
cout << "Zadejte sirku: ";
cin >> sirka;
cout << "a vysku: ";
cin >> vyska;
cout << "Zadali jste rozmery: " << sirka << "x" << vyska << ".";

Řešení situace, kdy uživatel zadá cokoliv jiného, než je očekávaný vstup (tedy celá čísla), si ukážeme někdy příště, protože zatím nemáme dostatek znalostí k tomu, abychom mu dokázali patřičně vynadat.

Jednoduchá kalkulačka

Když už umíme číst ze vstupu, nebrání nám nic v tom, abychom si napsali náš první prográmek, který reaguje na vstup od uživatele. Bude to jednoduchá kalkulačka, která bude umět zatím pouze jednu funkci - sčítání. Program si nejprve od uživatele vyžádá dvě čísla, potom je sečte a výsledek zobrazí.

Nejdříve si definujeme proměnné, do kterých budeme čísla od uživatele ukládat:

int prvni, druhe;

Potom uživatele požádáme o zadání čísel:

cout << "Zadejte prvni cislo: "
cin >> prvni;
cout << "Zadejte druhe cislo: "
cin >> druhe;
cin.get();

Všimněte si posledního příkazu. Ten zde musí být proto, protože po přečtení čísla zbyl na vstupu ještě jeden nepřečtený znak, a to je konec řádku, který se vložil stiskem klávesy enter pro potvrzení čísla. Tento příkaz ho přečte a dál s ním už nic nedělá. Kdyby zde tento příkaz nebyl, tak by enter zůstal na vstupu a přečetl by se na konci programu, kde je také tento příkaz. Tzn. že by se program ihned ukončil a nečekal by na další enter od uživatele.

Před prvním čtením tento příkaz nemusí být, protože při čtení čísla se všechny bílé znaky před číslem ignorují (včetně enteru).

A nakonec sečteme a zobrazíme výsledek:

cout << "Soucet zadanych cisel je " << prvni + druhe << ".";

Celý program se vším všudy může vypadat takto:

#include <iostream>

using namespace std;

int main()
{
	int prvni, druhe;
	
	cout << "Zadejte prvni cislo: ";
	cin >> prvni;
	
	cout << "Zadejte druhe cislo: ";
	cin >> druhe;
	cin.get();
	
	cout << "Soucet zadanych cisel je " << prvni + druhe << ".";
	cout << endl;
	
	cout << "Stisknete enter pro ukonceni." << endl;
	cin.get();
	
	return 0;
}

Všimněte si, že program můžeme zpřehlednit vložením prázdných řádků.

Formátování zdrojového kódu

Pamatujete na první program z prvního dílu tohoto seriálu? Lze zapsat i takto:

#include <iostream>
using namespace std;int main(){cout<<"Ahoj, svete!";cin.get();return 0;}

Na první pohled vypadá úplně jinak, že? A přitom pro kompilátor se jedná o identický kód. Jiný je proto, protože jsem z programu odstranil všechny přebytečné bílé znaky (mezery, tabulátory a konce řádků). Většina jich lze z programu odstranit a význam se nezmění, ale kód ztratí svoji čitelnost. Některé bílé znaky odstranit nelze a to na místech, kde by kód dostal jiný smysl. Například kdybyste v příkazu:

int cislo = 5;

Vynechali mezeru mezi int a cislo, vzniklo by toto:

intcislo = 5;

Což už není deklarace proměnné cislo, ale pouze přiřazení čísla do proměnné s názvem intcislo.

Ale pokud napíšete toto:

int
cislo = 5;

Jedná se o správný kód - je jedno, který bílý znak použijete (zde je použit konec řádku).

Můžete využít toho, že formátování kódu je v C++ takto volné a psát jako prase, ale doporučuji vám to nedělat, protože se vám to může vymstít. Kód je potom nečitelný a nečte se špatně pouze vám, ale pokud budete v budoucnu programovat v týmu, tak i ostatním. A pokud nebudete dbát na formát kódu už od začátku, potom se to už špatně dohání.

Existuje několik nepsaných pravidel, jak formátovat kód a měli byste se jich držet:

  • Každý příkaz by měl být na samostatném řádku, případně na více, pokud je pro jeden řádek příliš dlouhý (je zvykem kód formátovat tak, aby měl na šířku maximálně 80 znaků - či jiný dohodnutý počet).
  • Přikazy by měly být zleva odsazené podle úrovně zanoření kódu (podle počtu složených závorek). Viz osazení ve funkci main. Odsazené mohou být dohodnutým počtem mezer (např. 2 nebo 4) nebo tabulátorem. Tabulátor má tu vlastnost, že jeho šířka je v IDE nastavitelná. To se dá brát jako výhoda i jako nevýhoda (potom se špatně formátuje na určitou délku řádku).
  • Binární operátory by z obou stran měli být oddělené mezerou. Unární by neměli být oddělené mezerou na té straně, kde je proměnná, ke které patří.
  • U kulatých závorek se mezery píšou pouze zvenku, ne zevnitř.
  • Středník se píše hned za poslední znak příkazu bez mezery.

A mnohem více, o dalších pravidlech si řekneme, až se naučíme další konstrukce jazyka.

Příště

Příště se podíváme na další datový typ a ukážeme si první konstrukci pro větvení našich programů - podmínku.

Hodnocení

Celkové hodnocení
5 hlasů
Vaše hodnocení
Vyberte počet hvězdiček

Komentáře

Jméno:
Předmět:
Komentář:
  :):-|:P:D;):(8)[evil][arrow][idea][?][!]
Kontrola:

9.11.2015 3:48:03 lklkasdlakslkas@yahoo.com




indeed if people do not have faith that all is considered lawful.

http://obatasamurat.acepsuherman.info/

kldklasdms
0
1

9.11.2015 3:47:08 jefry1253@yahoo.com

I can not comment I do not know and how in order to know ...

<a href="http://obatasamurat.acepsuherman.info/">Obat Alami asam Urat</a>

Jefry
0
0

12.9.2015 17:27:56 další

Je to dokonale, ale kdy bude další?

jakub
3
0
© 2011 - 2017 SuperMartas a Tomáš Hypeš