Obsah
V této části si ukážeme, jak nechat vykonat jen část kódu, případně jak některou část kódu nevykonat vůbec. Také si ukážeme jak vybrat některou variantu, podle aktuální hodnoty přepínače. V neposlední řadě se naučíme několik způsobů, jak opakovaně vykonávat skupiny příkazů.
Všechny tyto naše zvolené záměry budou vykonány za použití řídicích konstrukcí. S jejich pomocí bude náš program provádět právě ty příkazy, které požadujeme.
Potřebné znalosti | |
K zvládnutí obsahu této kapitoly je nutné mít znalosti z kapitoly 2 až 4 - umět napsat jednoduché programy s pomocí výrazů. Orientovat se v problematice operátorů a znát jejich prioritu. |
Výrazem je nejen aritmetický výraz, prostý výskyt konstantní hodnoty, konstanty či proměnné, ale i volání funkce a přiřazení. Jestliže výraz ukončíme symbolem ; (středník), získáme výrazový příkaz. Zkráceně mu budeme i dále říkat příkaz.
Prázdný příkaz je tvořen samotným středníkem. Dává nám v některých případech možnost, umístit nadbytečný středník ; do zdrojového textu.
V jazyku C můžeme spojit dva nebo více příkazů dohromady. Nazýváme to blok příkazů, nebo složený příkaz. Pro vytvoření bloku příkazů ohraničte příkazy v bloku otevírací a uzavírací složenou závorkou. Když to uděláte, budou příkazy v bloku představovat jednu logickou jednotku, kterou lze použít všude tam, kde lze použít jeden příkaz.
Blok příkazu si nejlépe ukážeme na často používaném příkazu if.
Příklad: | |
if(výraz) { příkaz1; příkaz2; . . . příkazN; } else { příkaz1; příkaz2; . . . příkazN; } |
Pokud je výraz vyhodnocen jako pravdivý provedou se všechny příkazy uvedené v bloku za if. Budou prováděny v pořadí v jakém byly zapsány. Je-li výraz nepravdivý provedou se všechny příkazy bloku následující za else.
Blok může obsahovat nejen lokální proměnné, ale obecně v něm mohou být libovolné lokální deklarace a definice. Ovšem pouze na začátku bloku. Jejich platnost je omezena na blok a případné další vnořené bloky. Lokální proměnné v bloku mají paměťovou třídu auto. Vnořený blok nemusí být ukončen středníkem. Je vhodné si uvědomit, že tělo každé funkce je blokem. Proto můžeme v těle funkce main(void) definovat a používat lokální proměnné. Blok tedy může obsahovat žádnou, jednu či více deklarací. Dále blok může obsahovat jednotlivé příkazy.
Identifikátor, který deklarujeme či definujeme, si ponechává svůj význam (platnost) v programu či bloku, v němž je deklarován či definován. Jeho jméno je v tomto rozsahu viditelné, není-li překryto: |
Jméno makra je platné od jeho definice(direktivou define) až do místa, kdy je definice odstraněna (direktivou undef), pokud vůbec odstraněna je. Jméno makra nemůže být maskováno. To vyplývá z toho, že makra zpracovává preprocesor.
Příkaz if-else je jedním z příkazů jazyka C pro větvení programu. Často je také nazýván podmíněný příkaz. Jeho činnost je určena výsledkem testu podmínky, která je vyhodnocena jako pravdivá či nepravdivá.
Syntaxe příkazu if-else je jednoduchá, je však nutné zvýraznit, že výraz (podmínka splnění) musí být uzavřen v kulatých závorkách.
Je-li podmínka splněna, tedy výraz dává nenulovou hodnotu, vykoná se příkaz1, pokud podmínka splněna není, tedy výsledkem výrazu je nula, vykoná se příkaz2. Po vykonání jednoho z příkazů pokračuje chod programu za podmíněným příkazem.
Pro názorné pochopení příkazu if-else si ukažme jeho činnost na programu. Naším úkolem bude přečíst znak a pokud to bude velké písmeno vypsat jeho ordinální hodnotu, v opačném případě vypsat hlášení o tom, že nejde o velké písmeno.
Další příklad požádá o zadání dvou čísel a vytiskne jejich podíl. V případě, že se budeme snažit dělit nulou vytiskne chybové hlášení.
Další ilustrační jednoduché příkazy použití If-else:
Příklad: | |
if (i > 3) j = 5; |
Příklad: | |
if (i > 3) j = 5; else j = 1; |
Složený příkaz je nutné uzavřít do bloku za pomoci závorek { a }. Tento blok však nesmí být ukončen středníkem ;
Příklad: | |
if (i > 3) { j = 5; i = 7; } /* zde nesmí být žádný středník */ else if (i < 1) j = 1; else j = 0; |
Samozřejmě že není nutné používat pouze konstrukce If-else. Můžeme použít jak zjednodušenou variantu se syntaxí:
případně variantu více rozvitou, se syntaxí:
if (výraz1) příkaz1; else if (výraz2) příkaz2; else if (výraz3) příkaz3; ... else if (výrazN) příkazN; else příkazN+1; |
if (vyraz != 0) se píše if (vyraz)
a místo příkazu:
if (vyraz == 0) se píše if (!vyraz)
Ikdyž je příkaz if dobrý pro výběr ze dvou možností, stává se těžkopádným, když je potřeba pracovat s několika možnostmi. Jazyk C řeší tento problém příkazem switch. Příkaz switch je příkaz pro vícenásobný výběr. Používá se pro volbu jedné z několika variant a pracuje následovně. Hodnota je postupně testována podle seznamu celočíselných nebo znakových konstant. Když je nalezena shoda, provede se posloupnost příkazů spojená s touto hodnotou.
Obecný tvar příkazu switch je následující:
switch (celočíselný výraz) { case hodnota1: příkaz1; case hodnota2: příkaz2; . . . . . . case hodnotaN: příkazN; default: příkazD; } |
Nyní si popíšeme jaké konstrukce nám přepínač umožňuje vytvořit. Po klíčovém slově switch následuje v závorkách uzavřený celočíselný výraz. Za ním obecně následuje příkaz. Příkaz přepínače je tvořen blokem, neboť jinak bychom jen těžko mohli hovořit o přepínači mezi více variantami. V bloku jsou jednotlivé příkazy, příkaz1, příkaz2, ..., příkazN a příkazD. V tomtéž bloku mohou být po některé příkazy označeny speciálně umístěnou celočíselnou konstantou - mezi klíčovým slovem case a dvojtečkou.
Posloupnost příkazů pro default se provádí, když není nalezena žádná shoda. Část default je nepovinná. Pokud všechna porovnání selžou a default chybí, neprovede se žádná činnost.
A nyní si pokusíme vysvětlit význam přepínače switch. Během chodu programu je vyhodnocen celočíselný výraz. Podle jeho konkrétní hodnoty, je v bloku přepínače nalezena odpovídající hodnota, hodnota1, hodnota2, .... hodnotaN za kterou se přenese další chod programu. Provede se první příkaz za označeným místem, pak druhý, třetí, ..., dokud se nenarazí na konec bloku přepínače, nebo na zarážku break. Tím je ukončeno vykonávání přepínače a pokračuje se příkazem, který je v programu zapsán za příkazem přepínač.
Nyní, po trošce teorie, si ukážeme použití switch v praxi.
Naším úkolem je napsat program, ve kterém rozpoznáváme stisknuté klávesy 1 - 3 a vytiskneme název zadané klávesy. To znamená že po stisku 2 vypíše program dvě. Pokud zadáme jiné klávesy, než ty které zachytáváme vypíše program hlášení: Jiná klávesa.
Zamysleme se chvíli na tím, co by se stalo, kdyby v části kde kontrolujeme zda byla stisknuta klávesa 1 nebyl příkaz break. V tom případě by zápis vypadal následovně:
V tomto případě by při stisku klávesy 1 bylo vytisknuto:
Stiskl jsi klávesu 1 Stiskl jsi klávesu 2
Jak je vidět klíčové slovo break je velice důležité.
Cyklus je část programu, která je v závislosti na podmínce prováděna opakovaně. U cyklu obvykle rozlišujeme řídicí podmínku cyklu. Řídicí podmínka cyklu určuje, bude-li provedeno tělo cyklu, či bude-li řízení předáno za příkaz cyklu. Tělo cyklu je příkaz, zpravidla zapsaný v podobě bloku.
Cykly můžeme rozdělit podle toho, provede-li se tělo alespoň jedenkrát, a cykly, kde tělo nemusí být provedeno vůbec. Výběr typu cyklu ponechejme na vhodnosti použití v dané situaci i na zvyklostech programátora.
Podmínka cyklu while se testuje před průchodem cyklu, což znamená, že cyklus tedy vůbec nemusí proběhnout. Programový kód pro výraz musí být uzavřen v kulatých závorkách.
Syntaxe příkazu while je následující:
Začátečníci se často mylně domnívají, že když se při vykonávání těla cyklu změní hodnoty, na jejichž základě se vyhodnocuje řídcí podmínka cyklu, tedy výraz, projeví se to okamžitě změnou řízení chodu programu. Skutečnost je taková, že se dokončí vykonávání těla cyklu teprve poté je znovu vyhodnocena řídicí podmínka cyklu.
Správné pochopení cyklu while si nyní ukážeme na příkladu. V prvním příkladu budeme číst znaky z klávesnice do té doby dokud nestiskneme klávesu 'z' a všechny tisknutelné znaky budeme opět vypisovat na obrazovku.
Nyní si ukážeme tentýž příklad pouze s použitím nekonečného cyklu while a s použitím příkazů break a continue.
Pozn: | |
Tělo cyklu while může být také prázdné, například pokud chceme přeskočit všechny oddělovače na vstupu. |
Cyklus for se používá pro zadaný počet opakování příkazu nebo bloku příkazu. Má následující syntaxi:
Část inicializace se používá pro zadání počáteční hodnoty proměnné, která řídí průběh cyklu. Tato hodnota se obvykle označuje jako řídící proměnná cyklu. Část inicializace se provádí pouze jednou před začátkem cyklu. Část test-podmínky testuje řídící proměnnou cyklu na koncovou hodnotu. Je-li test podmínky vyhodnocen jako pravdivý, cyklus se opakuje. Je-li nepravdivý, cyklus se ukončí a zpracování programu pokračuje příkazem následujícím za cyklem. Test podmínky se provádí na začátku cyklu neboli před každým opakováním těla cyklu. Část inkrementace cyklu for se provádí na konci cyklu. To znamená, že část inkrementace se provádí poté, co se provede příkaz nebo blok, který tvoří tělo cyklu. Účelem inkrementace je zvyšovat (nebo snižovat) řídící proměnnou cyklu o určitou hodnotu.
Část inkrementace je nepovinná. Typicky se jedná o přípravu další iterace cyklu. Pokud neuvedeme testovací výraz test-podmínky, použije překladač hodnotu jedna, a tedy bude provádět nekonečný cyklus. Naštěstí můžeme použít příkazy break a continue se stejným významem, jaký jsme popsali u cyklu while.
Jako první jednoduchý příkaz si ukážeme program který vypíše čísla od 1 do 10.
Příklad 5.7. | |
/****************************** * for_1.c * 19.03.2002 ******************************/ #include <stdio.h> int main(void) { int i, cislo; for(i=1; i<=10; i++) printf("%d ",i); return 0; } |
Program pracuje následovně:
Nejprve se inicializuje řídící proměnná cyklu i na hodnotu 1. Pak se vyhodnotí příkaz i<=10 a jelikož je pravdivý začne běžet cyklus for. Po vytisknutí čísla se i zvětší o 1 a znovu se vyhodnotí test podmínky. Tento proces pokračuje do té doby, dokud není i rovno 11. Když k tomu dojde, cyklus for se zastaví a ukončí.
Mějme na paměti, že se podmínka cyklu vyhodnocuje na začátku každého opakování. To znamená, že je-li test na začátku cyklu nepravdivý, neprovede se tělo cyklu ani jednou. |
Zkusme si další příklad, který vypočítá součet a součin čísel od 1 do 5.
Nyní si ukážeme některé další možné použití cyklu for. Navážeme na náš předchozí příklad a opět se budeme snažit tisknout čísla od 1 do 10.
Příklad: | |
|
Často se používá i nekonečný cyklus, který má tvar:
Příkaz do je jediným z cyklů, který zajišťuje alespoň jedno provedení těla cyklu. Jinak řečeno, jeho testovací příkaz příkaz je testován až po průchodu tělem cyklu. Pokud je test, představovaný hodnotou získanou z výrazu splněn, provádí se tělo cyklu, tedy příkaz, který je typicky blokem.
Syntaxe:
Opět provedeme naše již známé načítání znaků z klávesnice, ovšem tentokrát vytiskneme i koncový znak z.
Mohlo by se zdát, že cyklus typu do-while je zbytečný. Totéž bychom ovšem mohli tvrdit i o cyklu for. Programátorská teorie totiž ukazuje, že pomocí cyklu typu while jsme schopni naprogramovat jakýkoliv cyklus. Programátorská realita nám ukazuje, že existence tří možných typů cyklů má své opodstatnění - to, co si programátor oblíbí, to rád a správně používá.
Jazyk C podporu příkaz nepodmíněného skoku nazvaný goto. Většina programátorů však příkaz goto nepoužívá, protože narušuje strukturu programu a pokud je používán často stává se napsaný kód nepřehledným. Později se může stát, že bude velice těžké pochopit správnou funkci takto napsaného programu.
Příkaz goto může provádět skok v rámci funkce. Nemůže však přeskakovat mezi dvěma funkcemi. Používá se spolu s návěstím.
Syntaxe: