přejít na obsah přejít na navigaci

Linux E X P R E S, Programovanie v jazyku C++: Príkaz goto

Control

Programovanie v jazyku C++: Príkaz goto

cplusplus.png

Minule sme riešili príkazy break a continue. V tomto článku pokračujeme ďalším zo základných príkazov jazyka C++: príkazom goto.


reklama

Príkaz goto

Minule ste sa dozvedeli, že s pomocou príkazu break viete rýchlo opustiť aktívny cyklus. Teraz si ale predstavíme podobný príkaz, ktorý nám skočí tam, kam chceme. Bude reč o príkaze goto. Práve tento príkaz nám zabezpečí, že môžeme opustiť cyklus a v definovanom odkaze môže program pokračovať.

1. príklad: Učíme sa príkaz goto

#include <iostream>   // hlavičkový súbor
using namespace std;   // priestor mien
int main()   // hlavná funkcia
{
    cout << "Idem pocitat od 0 do 9! Ale cinkni mi prikazom goto, ze mam skoncit!\n";
    for (int i = 0; i < 1000; i++)   // cyklus
    {
        cout << "Pocitam: "<<i<<"\n";
        if (i >= 9)
            goto skonci;   // využívame príkaz goto
    }
    skonci:   // štítok, odkaz na ktorý sa odvoláva príkaz goto
        cout<<"A padla! Hurra!";
}

Výsledok programu:

Idem pocitat od 0 do 9! Ale cinkni mi prikazom goto, ze mam skoncit!
 Pocitam: 0
 Pocitam: 1
 Pocitam: 2
 Pocitam: 3
 Pocitam: 4
 Pocitam: 5
 Pocitam: 6
 Pocitam: 7
 Pocitam: 8
 Pocitam: 9
 A padla! Hurra!

Rozbor programu: Príkaz goto sa uskutoční vtedy, ak premenná i bude mať hodnotu 9. Čo sa stane? Skok na definovanú oblasť, ktorú sme definovali. V našom prípade je to oblasť skonci. Danú oblasť alebo inak povedané aj štítok alebo odkaz, sme definovali takto: skonci: . Týmto sa začne vykonávať postupnosť príkazov, ktorá je definovaná za odkazom.

No fajn, poďme si to skomplikovať.

2. príklad:

#include <iostream>
 
 using namespace std;
 
 int main()
 {
     for (int i = 1; i < 6; i++)
     {
         cout <<i<<" + "<<i<<" je: "<<i+i<<"\n";
         if (i >= 5)
             goto odcitaj;
     }
 
     vydel:   cout << "\n";
              cout <<"1"<<" / "<<"1"<<" je: "<<1/1<<"\n";
              cout <<"2"<<" / "<<"2"<<" je: "<<2/2<<"\n";
              cout <<"3"<<" / "<<"3"<<" je: "<<3/3<<"\n";
              cout <<"4"<<" / "<<"4"<<" je: "<<4/4<<"\n";
              cout <<"5"<<" / "<<"5"<<" je: "<<5/5<<"\n";
 
              goto koniec;
 
     odcitaj: cout << "\n";
              cout <<"1"<<" - "<<"1"<<" je: "<<1-1<<"\n";
              cout <<"2"<<" - "<<"2"<<" je: "<<2-2<<"\n";
              cout <<"3"<<" - "<<"3"<<" je: "<<3-3<<"\n";
              cout <<"4"<<" - "<<"4"<<" je: "<<4-4<<"\n";
              cout <<"5"<<" - "<<"5"<<" je: "<<5-5<<"\n";
 
              goto vynasob;
 
     vynasob: cout << "\n";
 
              for (int i = 1; i < 6; i++)
              {
                 cout <<i<<" * "<<i<<" je: "<<i*i<<"\n";
                 if (i >= 5)
                     goto vydel;
              }
 
     koniec: return 0;
 }

Výsledok programu:

1 + 1 je: 2
 2 + 2 je: 4
 3 + 3 je: 6
 4 + 4 je: 8
 5 + 5 je: 10
1 - 1 je: 0
 2 - 2 je: 0
 3 - 3 je: 0
 4 - 4 je: 0
 5 - 5 je: 0
1 * 1 je: 1
 2 * 2 je: 4
 3 * 3 je: 9
 4 * 4 je: 16
 5 * 5 je: 25
1 / 1 je: 1
 2 / 2 je: 1
 3 / 3 je: 1
 4 / 4 je: 1
 5 / 5 je: 1

Rozbor programu: Využili sme v programe viacero skokov. Ako vidíte, skoky nie sú limitované na zhora dole architektúru, ako v klasickom behu programu. To znamená, že časť programu, ktorý je dole v programe, avšak vyvolaný skok sa môže nachádzať kľudne na začiatku programu. No, ale nie vo všetkom je taká idylka. Čo by sa stalo, ak by sme nedali skok koniec v častí vydel?



3. program: Modifikácia druhého programu: 

#include <iostream>
 
 using namespace std;
 
 int main()
 {
     for (int i = 1; i < 6; i++)
     {
         cout <<i<<" + "<<i<<" je: "<<i+i<<"\n";
 
         if (i >= 5)
             goto odcitaj;
     }
 
     vydel:   cout << "\n";
              cout <<"1"<<" / "<<"1"<<" je: "<<1/1<<"\n";
              cout <<"2"<<" / "<<"2"<<" je: "<<2/2<<"\n";
              cout <<"3"<<" / "<<"3"<<" je: "<<3/3<<"\n";
              cout <<"4"<<" / "<<"4"<<" je: "<<4/4<<"\n";
              cout <<"5"<<" / "<<"5"<<" je: "<<5/5<<"\n";
 
     odcitaj: cout << "\n";
              cout <<"1"<<" - "<<"1"<<" je: "<<1-1<<"\n";
              cout <<"2"<<" - "<<"2"<<" je: "<<2-2<<"\n";
              cout <<"3"<<" - "<<"3"<<" je: "<<3-3<<"\n";
              cout <<"4"<<" - "<<"4"<<" je: "<<4-4<<"\n";
              cout <<"5"<<" - "<<"5"<<" je: "<<5-5<<"\n";
 
              goto vynasob;
 
     vynasob: cout << "\n";
 
              for (int i = 1; i < 6; i++)
              {
                 cout <<i<<" * "<<i<<" je: "<<i*i<<"\n";
 
                 if (i >= 5)
                     goto vydel;
              }
 }

Výsledok programu: Nikdy nekončiaci program.

Rozbor programu: Keďže sme nedefinovali koniec programu, tak po dokončení častí vydel program pokračuje typický zhora na dol a tak sa uzavrie do nekonečnej slučky.

No a nakoniec, ak neholdujete cyklom ako for, while alebo mutácie whilu ako do-while, tak vám môže napomôcť príkaz goto. Ale popravde, využívať goto ako cyklus je zbytočný luxus. Ale ako zaujímavosť si ukážme cyklus v podaní goto.

4. program: Cyklus v podaní príkazu goto. 

#include <iostream>
 
 using namespace std;
 
 int main()
 {
     int i = 0;
 
     vynasob:
         i++;
 
         cout <<i<<" + "<<i<<" je: "<<i+i<<"\n";
 
         if(i >= 5)
             goto theEndKonecneJuj;
 
         goto vynasob;   // goto ako cyklus
 
     theEndKonecneJuj: return 0;
 }

Výsledok programu: 

1 + 1 je: 2
2 + 2 je: 4
3 + 3 je: 6
4 + 4 je: 8
5 + 5 je: 10

Rozbor programu: Kód programu už dôverne poznáte (ak ste poctivo vyriešili všetky programy v tomto článku). Všimnite si, ako elegantne sme vytvorili z goto cyklus.

Poznámka šéfredaktora: Příkazu goto je dobré se v C++ (i v C, ale tam má jeho použití v některých případech pádné důvody a například v linuxovém jádře se využívá poměrně hojně) vyhnout, pokud to jde – a jde to prakticky vždy. Použití goto totiž znepřehledňuje program a komplikuje pochopení jeho běhu.



Nahoru

Příspěvky

Programovanie v jazyku C++: Príkaz goto
fela 29. 04. 2017, 13:12:43
Odpovědět  Odkaz 
Ad 'Poznámka šéfredaktora': Presne tak, vynúť sa dá vždy, aj keď niekedy je ktomu potrebných viac zanorených cyklov, podmienkové premenné,...
Programovanie v jazyku C++: Príkaz goto
Jiří K. 29. 04. 2017, 15:01:56
Odpovědět  Odkaz 
Při první přednášce Základů programování nám přednášející řekl, že od zkoušky vyrazí každého, kdo "goto" použije. Podle něj neexistuje opodstatněný důvod pro existenci takového příkazu.
Lukáš Jelínek Re: Programovanie v jazyku C++: Príkaz goto
Lukáš Jelínek 29. 04. 2017, 21:48:26
Odpovědět  Odkaz 
V linuxovém jádře se goto poměrně vydatně používá, protože C na rozdíl od C++ neobsahuje výjimky. Typicky v ovladačích může nějaká operace selhat na celé řadě míst a po selhání je potřeba vše uvést do řádného stavu (především uvolnit všechny alokované prostředky, vrátit nastavení zařízení apod.). Pokud se to bude řešit jen vnořenými podmínkami, vznikne tím nepřehledný a špatně spravovatelný kód. Tady je použití goto zcela na místě, vytvoří takovou "cibuli", která zajistí řádný úklid pro jakékoli selhání a zároveň je přehledná.

Je to vidět třeba tady (vybral jsem náhodně jeden zdrojový soubor, podobných je tam spousta): http://lxr.free-electrons.com/source/drivers/char/hw_random/core.c
Vojtěch Trefný Re: Programovanie v jazyku C++: Príkaz goto
Vojtěch Trefný 30. 04. 2017, 14:12:35
Odpovědět  Odkaz 
Ve škole a obzvlášť v předmětech co mají v názvu "základy" nebo "úvod" se napovídá spousta věcí, které nejsou pravda :-)

Fakt ale je, že při programování ve škole těžko někdo narazí na problém, kdy by bylo opodstatněné goto použít, a je celkem rozumné ho studentům zakazovat -- ono goto je takové "lákavé", umožňuje hodně si zjednodušit život (aspoň teda dočasně) a vyhnout se těm "správným ale složitým" postupům.

Jinak tedy v článku jsou spíš ukázky toho, kdy goto skutečně nepoužít a když to někdo udělá (jinde než v ukázce, nejlépe odstrašující) tak by zasloužil zlomit klávesnici :-)

Co tedy rozhodně nedělat:
- Víc labelů v jedné funkci. Když se navíc na každý skáče vícekrát, tak aby si člověk pomalu maloval, co ta funkce vlastně dělá.
- goto v cyklu. Na ukočení cyklu prostě slouží break.
- Skoky "nahoru" ve funkci. Skok "zpátky" strašně znepřehledňuje průběh funkce. Takové goto je obvykle znakem toho, že by se z části kódu měla udělat samostatná funkce.

Obecně bych byl proti jakémukoli goto, které implementuje nějakou "funkcionalitu" -- tedy dělá něco, co nějak souvisí se samotným účelem funkce.

Osobně uznávám jen takové to klasické "goto out;", které už tu zmiňoval Lukáš -- skok na konec funkce, kde se vyřeší return a uvolňování paměti (prostředků obecně) na jednom místě, aby to nebylo třeba řešit v každém ifu.
Programovanie v jazyku C++: Príkaz goto
bobo 23. 06. 2017, 13:02:24
Odpovědět  Odkaz 
Kod, ktory vyhlada prvy nulovy prvok v n-dimenzionalnom (napr. n=3 => 3x vnoreny cyklus) poli je s goto ovela citatelnejsi, ako po kazdom cykle testovat nejaku stavovu premennu.

BTW, assembler bez prikazu goto (JUMP) by ani nemohol existovat.

Aby to bolo jasnejsie: Ak programovaci jazyk goto umoznuje, nie je vhodne ho studentom zakazovat pouzivat, alebo ich zo skusky za pouzitie vyhadzovat, pripadne im "lamat klavesnicu". Kazdy nech sa nauci na vlastnych chybach, ak to mysli s programovanim v C++ vazne. Ked niekto goto nevie pouzivat a robi mu problemy, tak nech ho ani nepouziva a najlepsie ani C++, aby nahodou nezabudol napr. dealokovat pole alebo zavolat destruktor.

Přidat názor

Nejsou podporovány žádné značky, komentáře jsou jen čistě textové. Více o diskuzích a pravidlech najdete v nápovědě.
Diskuzi můžete sledovat pomocí RSS kanálu rss



 
 

Top články z OpenOffice.cz

Eduard Boldižár

Eduard Boldižár

Som redaktorom stránky astrotech.cz. Mám 24 rokov. Čas trávim v IT škole. Medzi moje záľuby patrí astronómia, sci-fi literatúra a programovanie.


  • Distribuce: ubuntu
  • Grafické prostředí: unity