Programujeme ve Visual Basic .NET - 9. díl - smyčka s čítačem

V tomto dílu se budeme věnovat řídícím strukturám jazyka VB.NET pro provádění konečného počtu cyklů.
V minulém díle seriálu jsme s využitím znalostí příkazů cyklu Do - Loop a pro podmíněného provádění příkazu Exit Do sestavili program pro výpočet součtu čísel od nuly do předem dané hodnoty. Přestože byl náš sčítací prográmek docela krátký, lze jej zapsat ještě o něco úsporněji a především efektivněji s využitím příkazem cyklu s čítačem (někdy též "konečné smyčky"). Hlavní výhoda smyčky s čítačem je v případech, kdy známe počet průchodů kódu cyklem předem a tkví v tom, že nemusíme v každém cyklu kontrolovat kritérium pro opuštění nekonečného cyklu, protože je za nás provádí běhové prostředí VB.NET. Další výhodou je, že program využívající smyčky s pevně daným konečným počtem cyklů nemůže při nesplnění podmínky uváznout v nekonečné smyčce - jeho provádění je tudíž mnohem robustnější a odolné proti logickým chybám v kódu. A poslední významný důvod pro použití konstrukcí s počítanými cykly spočívá ve výrazném zjednodušení a zpřehlednění programu. Z těchto důvodů bychom měli dávat smyčkám s čítačem vždy přednost před nekonečným smyčkám s logickými podmínkami, pokud je to možné.

Řídící příkaz cyklu For - Next s čítačem

Pro realizaci konečné smyčky VB.NET využívá konstrukci For..Next, která ve svém nejobecnějším provedení obsahuje čtyři průběžně se měnící výrazy - v první řadě proměnnou čítač (tzv. counter nebo někdy též řídící proměnná cyklu), dále hodnoty počátečního a konečného stavu čítače a konečně velikost tzv. kroku cyklu, tj. hodnoty, o kterou bude hodnota proměnné čítače v každém průběhu změněna. Podle toho, zda je hodnota kroku cyklu kladná nebo záporná, by měla být velikost počáteční hodnoty čítače cyklu větší nebo menší, než konečná hodnota, aby byl cyklus proveden alespoň jedenkrát. Všechny příkazy uvnitř těla takové smyčky budou prováděny pro hodnoty proměnné counter, postupně se měnící od hodnoty dané výrazem counter_start do hodnoty výrazu counter_stop s krokem odpovídající hodnotě výrazu counter_step. Stejně jako v nekonečné smyčce, i v cyklu For - Next je dobrým zvykem příkazy ve vnitřním těle cyklu odsazovat mezerami nebo tabelátory z důvodu přehlednosti:

    For counter = counter_start To counter_stop Step counter_step
      ....
      ....
    Next counter 

Zatímco counter je vždy číselnou proměnnou, výrazy counter_start, counter_stop a counter_step mohou tvořit jak číselné konstanty, tak proměnné, nebo dokonce složitější výrazy z nich složené - není však vhodné takové výrazy v smyčce  For - Next využívat, protože se tím značně komplikuje chování cyklu, který může díky tomu dokonce uváznout v nekonečné smyčce. Pokud je hodnota výrazu counter_step rovna jedné, nemusíme klíčové slovo Step a hodnotu kroku vůbec uvádět, jelikož jednička je výchozím krokem každého počítaného cyklu. Z výše uvedeného vyplývá, že oba zápisy cyklu For...Next uvedené níže jsou rovnocenné:

    For incr = 1 To 100 Step 1
      suma = suma + incr
    Next incr
nebo
For incr = 1 To 100
suma = suma + incr
Next

V případě, že výraz counter_step tvoří necelý zlomek rozdílu výrazů (counter_stop - counter_start), musíme počítat s tím, že se provádění smyčky ukončí vždy před dosažením hodnoty counter_stop, pokud by v příštím kroku došlo k jejímu překročení - viz níže uvedený příklad:

    Dim i
    For i = 0 To 10 Step 3
      System.Console.WriteLine(i)
    Next i      

vypíše hodnoty (hodnoty 10 tedy nebude nikdy dosaženo!):

0
3
6
9

Uvedená vlastnost smyčky For - Next se může stát zdrojem poměrně záludných chyb v případě, že při postupném přičítání kroku v podobě desetinného čísla dojde ke kumulaci zaokrouhlovacích chyb. Proto při použití smyčky For - Next dáváme v zájmu reprodukovatelnosti a rychlosti přednost cyklům s čítačem v pevné řádové čárce, např. místo:

    For i = 0 To 1 Step 0.3
a = i
Next i
dáme přednost:
For i = 0 To 10 Step 3
a = i / 10
Next i

Vnořené smyčky For - Next

Řídící proměnnou lze vynechat i za příkazem Next, pokud ji však použijeme, musíme při vnořování smyček dbát na to, aby nedošlo k prohození řídících proměnných vnitřního a vnějšího cyklu  (v tom případě překladač VB.NET oznámí chybu překladu ve stylu "Řídicí proměnná příkazu Next neodpovídá řídicí proměnné příkazu smyčky For") - např. takto:

    For i = 1 To iMAX
      For j = 1 To jMAX
        ......
      Next i        ` ......chyba !
    Next j

Smyčka s čítačem jako pojistka nekonečné smyčky

Ačkoliv se konečná smyčka For..Next provádí předem daný počet cyklů, je možné stejně jako v případě konstrukce Do ..Loop smyčku předčasně opustit při splnění nějaké logické podmínky pomocí příkazu Exit For. Konstrukce  For..Next se v tom případě často používá jako omezení maximálního běhu nekonečné smyčky, např. při zadání nekorektní hodnoty iMAX uživatelem:

    Dim i
    For i = 1 To iMAX
      ...
      If i > 1000 Then Exit For
    Next    

Blokovací smyčky ve VB.NET

Ve starších verzích Basicu se smyčka často používaly ke záměrnému zpomalení programu, tj. jeho zdržení na určitou dobu nějakým neužitečným výpočtem (tzv. "blokovací", resp. "zpomalovací" smyčka) - např. ve hrách aj. situacích, jejichž rychlost nemá záviset na frekvenci procesoru. Tento postup je však ve VB.NET zcela zbytečný a zastaralý, protože rozhraní .NET podporuje možnost pozastavení běhu programu systémově, např. pomocí metody System.Thread.Sleep(), o které se zmínime při popisu práce s thready. Na tomto místě proto jen stručnou ukázku - pozastavení běhu programu na 3 vteřiny (tj. 3000 milisekund) dosáhneme v kódu voláním:

....
System.Threading.Thread.Sleep(3000)
....

Uvedený způsob má oproti blokovací smyčce výhodu v tom, že k pozastavení běhu programu dochází na předem definovanou dobu nezávislou na taktu procesoru, prioritě procesu, atd. a během pauzy nedochází k zbytečnému vytěžování procesoru - což má význam především v počítačích napájených z baterie. Další možností je využití událostního modelu třídy Timer (časovač), která se často používá pro běh programu "na pozadí" a seznámíme se s ním rovněž později.

Ukázkový program pro výpočet součtu čísel od jedné do sta s využitím For - Next

Upravíme-li s použitím  příkazu cyklu For - Next náš prográmek pro výpočet součtu čísel od jedné do sta, dojde k podstatnému zjednodušení a zpřehlednění kódu:

    Module modMain
      Sub Main
        Const iMAX = 100
        Dim suma = 0, incr
        For incr = 1 To iMAX
          suma = suma + incr
        Next incr
        System.Console.WriteLine(suma)
      End Sub
    End Module

Poznámka

Přiřazení suma = suma + incr lze též zkráceně zapsat spojením operátorů sčítání a přiřazení do jediného jako suma += incr. Ačkoliv je tento zkrácený způsob zápisu (tzv. "syntax sugar") méně přehledný, používá se často v jazycích odvozených od C, tedy C++, JScript i C# a lze jej  použít i ve VB.NET (analogicky lze zapsat i přiřazení s dalšími operátory, např. násobení). S použitím zkrácené verze pak vypadá příkaz cyklu následovně:

    Dim incr
    For incr = 1 To iMAX
      suma += incr
    Next

Stručné shrnutí

Pro opakované provádění kódu po předem známý počet kroků je možné s výhodou použít konstrukci For - Next, která vyžaduje deklaraci řídící proměnné cyklu (čítače), definování její počáteční a konečné hodnoty a velikosti kroku cyklu.

Diskuze (6) Další článek: Soubory: Nová verze českého OpenOffice ZDARMA!

Témata článku: Software, Programování, Díl, BAS, Loop, JMA, Zjednodušený příklad, Step, Visual, Pre, Významný důvod, Smyčka, Krok, Timer, Counter, IMAX, Vnější provedení, Citace, Exit, Podstatné zjednodušení, Uvedený způsob, Suma, Next, Sumo, Forum



25 nejlepších filmových parodií, které můžete vidět. Víme, kde je najdete online

25 nejlepších filmových parodií, které můžete vidět. Víme, kde je najdete online

Filmové parodie jsou divácky velmi vděčné a mezi filmaři oblíbené. Tvůrci v nich mohou totiž zcela beztrestně vykrádat cizí díla a v jejich nápodobě popustit uzdu své fantazii. Vybrali jsme nejlepší zahraniční i české parodie.

Jaromír PukMarek Čech
Filmy, které musíte vidět
Ubisoft v budoucnu plánuje upustit od AAA titulů a dá prostor free-to-play hrám

Ubisoft v budoucnu plánuje upustit od AAA titulů a dá prostor free-to-play hrám

Čtvrtletní finanční report Ubisoftu odhalil spoustu zajímavých informací. Tou hlavní ale je, že již tolik nechce lpět na vydávání 3-4 velkých titulů ročně.

Martin Nahodil
The Division: HeartlandUbisoftFree-to-play
IBM má první 2nm čip. Ale pozor – není nanometr jako nanometr

IBM má první 2nm čip. Ale pozor – není nanometr jako nanometr

** IBM se pochlubilo prvním 2nm čipem ** K výrobě byla použitá technologie EUV ** Oproti 7nm čipům sníží spotřebu o 75 %

Karel Javůrek
ČipyIBMTechnologie