10. Příkaz skoku

Na začátek této kapitoly bychom měli zdůraznit, že užívání příkazu skoku by se měl moderní programátor v C# vyhnout, pokud k tomu není nějakým způsobem nucen! Bez skoků se lze obejít (matematicky dokázáno) a programy jsou pak všeobecně přehlednější a bezpečnější. 

Příkaz skoku slouží ke skoku z jednoho místa ve zdrojovém kódu na jiné místo, které je označeno návěštím. Používá se např. k předčasnému ukončení nějakého strukturovaného příkazu, např. hluboce zapouzdřeného cyklu nebo u vícenásobného větvení. Nedoporučuje se používat pro běžné větvení programu!

Obecná syntaxe příkazu skoku v jazyce C#:

goto IdentifikátorNávěští

kde:

  •  goto - klíčové slovo pro příkaz skoku 
  • IdentifikátorNávěští - identifikátor návěští, kam se má přemístit vykonávání kódu z daného místa, kde byl kód vykonáván (místo kde je umístěn příkaz skoku)

Obecná syntaxe návěští je:

IdentifikátorNávěští:
	příkaz;

kde:

  • IdentifikátorNávěští: - definuje místo v kódu (návěští), odkud se mají vykonávat další příkazy, umístěné za tímto identifikátorem. Oborem platnosti návěští je tělo metody, ve které je návěští definováno

Ilustrativní příklad KalkulackaSkok

Algoritmus KalkulackaSkok

  • Popis: Vývojový diagram pro řešení aritmetických operací u dvou zadaných čísel - příkaz skoku
  • Zadání: Zkuste navrhnout v hlavním programu algoritmus KalkulackaSkok, který řeší základní aritmetické operace podle zadaného číselného kódu (1 … sčítání, 2 … odečítání, 3 … násobení a 4 … dělení) u dvou uživatelem zadaných čísel a a b. Rozhodování o provedení aritmetické operace bude provedeno pomocí vícenásobného větvení proměnné kod. Namísto příkazu break ve větvích použijte příkaz skoku, který provádění programu přemístí k návěští NavestiVypis. Pokud uživatel zadá špatný číselný kód, provede se větev default, kde se vypíše text "Zadali jste špatný číselný kód!" a provádění programu skočí na návěští s názvem NavestiKonec, které program ukončí. V případě dělení, pokud bude dělitel nulový, vypište uživateli hlášení "B nesmí být 0" a program ukončete pomocí příkazu skoku na návěští NavestiKonec. Výsledek aritmetické operace vypište v hlavním programu


Začátek algoritmu hlavního programu je stejný jako v předchozím algoritmu KalkulackaVicenasobneVetveni. Rozdíl spočívá v použití prvků s názvy návěští, tj. NavestiKonec, NavestiVypis. NavestiVypis využijeme tehdy, pokud má být dalším krokem vypsání vypočtené hodnoty uložené v lokální proměnné c. NavestiKonec využijeme k ukončení algoritmu v případě nesprávného zadání číselného kódu aritmetické operace. 

Na základě vývojového diagramu KalkulackaSkok vytvoříme v konzolové aplikaci program, na kterém si vysvětlíme příkaz skoku používaný v jazyce C#. Vývojový diagram algoritmu KalkulackaSkok byl vytvořen v aplikaci Visio s použitím dodatečně vytvořených vlastních značek deklarace proměnných, kterou využíváme v aplikaci Flowgorithm.


Program KalkulackaSkok

  • Popis: Hlavní metoda pro řešení aritmetických operací u dvou zadaných čísel - příkaz skoku
  • Zadání: Vymyslete, jak byste v C# naprogramovali hlavní metodu algoritmu KalkulackaSkok jako konzolovou aplikaci
  • Řešení: Bude postupně probráno v následujícím textu

Začátek zdrojového kódu je stejný jako v předchozím případu programu KalkulackaVicenasobneVetveni. Rozdíl spočívá v použití využity spojovací prvky s názvy návěští, tj. NavestiKonec, NavestiVypis. Pokud se v algoritmu přemístíme na návěští NavestiVypis bude proveden výpis v konzoli – viz Kód 1. V těle switch je také definována větev default, která obsahuje příkazy, pokud uživatele zadal jinou než povolenou hodnotu číselného kódu operace. 

Ve zdrojovém kódu, oproti předchozímu programu KalkulackaVicenasobneVetveni, jsme nahradili příkaz break (sloužící k ukončení složeného příkazu ve větvi vícenásobného větvení) a return (ukončující hlavní metodu) pomocí příkazu skoku, tj. pomocí klíčového slova goto. Ke konci zdrojového kódu jsme umístili dvě návěští – NavestiVypis a NavestiKonec. Kód nacházející se za návěštím NavestiVypis provede vypsání výsledku pomocí příkazu WriteLine. Po výpisu textu a hodnoty výsledku program se následně provede příkaz, který je umístěn za návěštím NavestiKonec (za návěštím musí být umístěn vždy nějaký příkaz. Lze použít i prázdný příkaz, tj. ;). Proto dbejte zvýšené opatrnosti s používáním příkazu skoku. Program je po provedení příkazu za návěštím NavestiVypis sekvenčně prováděn dál, tj. prochází další příkaz, který je umístěn za dalším návěštím NavestiKonec. Toto návěští jsme umístili těsně před konec těla metody a tím dojde k ukončení programu. Toto návěští využijeme jako nahrazení příkazu return.

Pokud nepožadujeme vypsat žádnou vypočtenou hodnotu v důsledku chyby (špatně zadaný číselný kód), stačí ukončit program. To provedeme pomocí skoku na návěští NavestiKonec.

Příkaz skoku lze také využít např. k přemístění do první sekce vícenásobného větvení v našem kódu použitím goto case 1.

static void Main(string[] args)
{
    /*Deklarace proměnných: 'kod' ... celočíselný kód aritmetické operace, 
     * 'a' ... první zadané číslo, 'b' ... druhé zadané číslo, 
     * 'c' ... výsledek aritmetické operace*/
    int kod;
    double a, b, c;
    //Výpis výzvy k zadání operace
    Console.Write("Zadejte kód operace (1 ... sčítání, 2 ... odečítání, " +
        "3 ... násobení, 4 ... dělení): ");
    //Načtení kódu operace
    kod = int.Parse(Console.ReadLine());
    //Výpis výzvy k zadání prvního čísla
    Console.Write("Zadejte A: ");
    //Načtení prvního zadaného čísla
    a = int.Parse(Console.ReadLine());
    //Výpis výzvy k zadání druhého čísla
    Console.Write("Zadejte B: ");
    //Načtení druhého zadaného čísla
    b = int.Parse(Console.ReadLine());
    //Přepnutí do příslušné sekce podle hodnoty kod
    switch (kod)
    {
        //Operace sečtení
        case 1:
            //Sečtení dvou zadaných čísel
            c = a + b;
            //Příkaz skoku na definované návěští
            goto NavestiVypis;
        //Operace odečtení
        case 2:
            //Odečtení dvou zadaných čísel
            c = a - b;
            //Příkaz skoku na definované návěští
            goto NavestiVypis;
 
        //Operace násobení
        case 3:
            //Násobení dvou zadaných čísel
            c = a * b;
            //Příkaz skoku na definované návěští
            goto NavestiVypis;
        //Operace dělení
        case 4:
            //Podíl dvou zadaných čísel
            c = a / b;
            //Příkaz skoku na definované návěští
            goto NavestiVypis;
        //Zadání špatného číselného kódu operace
        default:
            //Výpis chyby v zadávání kódu
            Console.WriteLine("Zadali jste špatný číselný kód!");
            //Příkaz skoku na definované návěští
            goto NavestiKonec;
    }
 
    //Definování návěští -> výpis -> ukončení
    NavestiVypis:
    //Výpis textu s hodnotou výsledku
    Console.WriteLine("Výsledek C: {0}", c);
 
    //Definování návěští -> ukončení
    NavestiKonec:
    //Čekání na stisk klávesy -> Ukončení programu
    Console.ReadKey();
}

Kód 1: Kód těla hlavní metody programu KalkulackaSkok – příklad použití skoku namísto příkazů return a break

Na základě výpisu v konzole vidíme, jak by mohl vypadat případ násobení dvou reálných čísel pomocí hlavní metody Main – viz Výstup programu 1 - Kód 1. 

Zadejte kód operace (1 ... sčítání, 2 ... odečítání, 3 ... násobení, 4 ... dělení): 3
Zadejte A: 7
Zadejte B: 5
Výsledek C: 30

Výstup programu 1 - Kód 1: Ukázka výsledku - násobení

A nyní zkusíme trochu škodit a otestovat funkčnost naší aplikace. Nastavme hodnotu číselného kódu aritmetické operace mimo povolené meze – viz Výstup programu 2 - Kód 1. Vidíme, že dojde k výpisu chybové hlášky.
Zadejte kód operace (1 ... sčítání, 2 ... odečítání, 3 ... násobení, 4 ... dělení): 5
Zadejte A: 7
Zadejte B: 5
Zadali jste špatný číselný kód!

Výstup programu 2 - Kód 1: Ukázka výsledku - chybný číselný kód aritmetické operace