Příkazy if, while, do-while, for, switch

Podobné dokumenty
Řídící struktury, if, while, switch

Řídící struktury, if, while, switch

Řídicí struktury. alg3 1

3. přednáška. Obsah: Řídící struktury sekvence, if-else, switch, for, while, do-while. Zpracování posloupnosti

Algoritmizace a programování

Algoritmizace a programování

6 Příkazy řízení toku

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

Funkce, intuitivní chápání složitosti

Algoritmizace a programování. Ak. rok 2012/2013 vbp 1. ze 44

8. lekce Úvod do jazyka C 3. část Základní příkazy jazyka C Miroslav Jílek

Začínáme vážně programovat. Řídící struktury Přetypování Vstupně výstupní operace Vlastní tvorba programů

Operační systémy. Cvičení 4: Programování v C pod Unixem

Algoritmizace a programování

Větvení a cykly. Úvod do programování 1 Tomáš Kühr

2.1 Podmínka typu case Cykly Cyklus s podmínkou na začátku Cyklus s podmínkou na konci... 5

Funkce, procedury, složitost

Programování v jazyce C pro chemiky (C2160) 3. Příkaz switch, příkaz cyklu for, operátory ++ a --, pole

Jazyk C++, některá rozšíření oproti C

Úvod do programování - Java. Cvičení č.4

Logické operace. Datový typ bool. Relační operátory. Logické operátory. IAJCE Přednáška č. 3. může nabýt hodnot: o true o false

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

Algoritmy I. Cvičení č. 2, 3 ALGI 2018/19

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Cykly. Základy programování 1 Martin Kauer (Tomáš Kühr)

Úvod do programování. Lekce 5

Programovací jazyk Pascal

Výrazy a operátory. Operátory Unární - unární a unární + Např.: a +b

Úvod do programování. Lekce 3

2. lekce Algoritmus, cyklus Miroslav Jílek

BI-PA1 Programování a Algoritmizace 1. Miroslav Baĺık, Ladislav Vagner a Josef Vogel. 7., 9. a 10. listopadu 2017

Jazyk C Program v jazyku C má následující strukturu: konstanty nebo proměnné musí Jednoduché datové typy: Strukturované datové typy Výrazy operátory

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

EVROPSKÝ SOCIÁLNÍ FOND. Úvod do PHP PRAHA & EU INVESTUJEME DO VAŠÍ BUDOUCNOSTI

Algoritmy a datové struktury

1. Téma 03 - Rozhodování

6. Příkazy a řídící struktury v Javě

Klíčové pojmy: Cyklus, řídící proměnná, inicializace, test podmínky, přerušení cyklu, vnořování cyklů.

Poslední nenulová číslice faktoriálu

Dekompozice problému, rekurze

Algoritmy. BI-PA1 Programování a Algoritmizace I. Ladislav Vagner

Jazyk C# a platforma.net

Programování v C++ 1, 1. cvičení

Pole a Funkce. Úvod do programování 1 Tomáš Kühr

9. lekce Úvod do jazyka C 4. část Funkce, rekurze Editace, kompilace, spuštění Miroslav Jílek

Programovani v Maplu Procedura

Funkce, podmíněný příkaz if-else, příkaz cyklu for

Algoritmy. BI-PA1 Programování a Algoritmizace 1. Miroslav Baĺık, Ladislav Vagner a Josef Vogel

Racionální čísla, operátory, výrazy, knihovní funkce

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

Algoritmizace a programování

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Pascal. Katedra aplikované kybernetiky. Ing. Miroslav Vavroušek. Verze 7

- jak udělat konstantu long int: L long velka = 78L;

BI-EP1 Efektivní programování 1

Funkce pokročilé možnosti. Úvod do programování 2 Tomáš Kühr

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

Programovací jazyk C++ Hodina 1

Preprocesor. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze. Karel Richta, Martin Hořeňovský, Aleš Hrabalík, 2016

Martin Flusser. November 1, 2016

1 PRVOCISLA: KRATKY UKAZKOVY PRIKLAD NA DEMONSTRACI BALIKU WEB 1

Programování v jazyce JavaScript

Iterační výpočty. Dokumentace k projektu č. 2 do IZP. 24. listopadu 2004

Programovací jazyk C(++) C++ area->vm_mm->locked_vm -= len >> PAGE_SHIFT;

Racionální čísla, operátory, výrazy, knihovní funkce

Dynamické datové struktury III.

Základní stavební prvky algoritmu

Programování v jazyce JavaScript

Obsah přednášky. Příkaz for neúplný. Příkaz for příklady. Cyklus for each (enhanced for loop) Příkaz for příklady

MQL4 COURSE. By Coders guru -5 Smyčky & Rozhodnutí Část 2

Přednáška 3. Rekurze 1

Programování: základní konstrukce, příklady, aplikace. IB111 Programování a algoritmizace

PROGRAMOVACÍ JAZYKY A PŘEKLADAČE REALIZACE PŘEKLADAČE I

Základy algoritmizace a programování

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016

Programování v jazyce C

Algoritmizace prostorových úloh

Obsah přednášky. programovacího jazyka. Motivace. Princip denotační sémantiky Sémantické funkce Výrazy Příkazy Vstup a výstup Kontinuace Program

Algoritmizace. 1. Úvod. Algoritmus

Rozklad problému na podproblémy, rekurze

Programování a algoritmizace

Příklady: (y + (sin(2*x) + 1)*2)/ /2 * 5 = 8.5 (1+3)/2 * 5 = /(2 * 5) = 1.3. Pavel Töpfer, 2017 Programování 1-3 1

Úvod do programovacích jazyků (Java)

2 Základní funkce a operátory V této kapitole se seznámíme s použitím funkce printf, probereme základní operátory a uvedeme nejdůležitější funkce.

Programování v C++, 2. cvičení

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

Abstraktní třídy, polymorfní struktury

Algoritmizace prostorových úloh

Základní datové typy, proměnné - deklarujeme předem - C je case sensitive rozlišuje malá a velká písmena v názvech proměnných a funkcí

BI-PA1 Programování a algoritmizace 1 Katedra teoretické informatiky

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Algoritmizace a programování

Abstraktní datové typy, moduly

Algoritmizace a programování. Ak. rok 2012/2013 vbp 1. ze 44

type Obdelnik = array [1..3, 1..4] of integer; var M: Obdelnik;

Seminář z IVT Algoritmizace. Slovanské gymnázium Olomouc Tomáš Kühr

Pseudonáhodná čísla = algoritmicky generovaná náhrada za náhodná čísla

SPJA, cvičení 1. ipython, python, skripty. základy syntaxe: základní datové typy, řetězce. podmínky: if-elif-else, vyhodnocení logických výrazů

Transkript:

Příkazy if, while, do-while, for, switch BI-PA1 Programování a Algoritmizace 1 Ladislav Vagner, Josef Vogel Katedra teoretické informatiky a Katedra softwarového inženýrství Fakulta informačních technologíı České vysoké učení technické v Praze xvagner@fit.cvut.cz, vogeljos@fit.cvut.cz 24. října 2016 a 27. října 2016

Přehled Řízení výpočtu. Příkaz if. Příkazy cyklu while, do-while, a for. Příkaz switch. L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 2/51

Řízení výpočtu Řízení výpočtu: sekvence příkazy se provádějí shora dolů,, větvení jeden nebo několik příkazů se provedou jen za splnění určité podmínky, cykly jeden nebo několik příkazů se provádí opakovaně v závislosti na splnění určité podmínky. Implementace: strukturované programování příkazy jsou ve formě bloků, bloky se používají ve větvích a cyklech (C/C++, Java, Pascal,... ), spaghetti code návěští a goto příkazy (původní BASIC). L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 3/51

Řízení výpočtu Sequence + If-then - L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 4/51

Řízení výpočtu If-then-else + - switch... L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 5/51

Řízení výpočtu while, for do-while - + + - L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 6/51

Řízení výpočtu Složený příkaz sekvence příkazů ve složených závorkách; považuje se za jediný příkaz (z hlediska syntaxe): { a = 10; b = 20; Blok sekvence deklarací a sekvence příkazů ve složených závorkách (blok může být i prázdný): definice funkcí jsou bloky (např. funkce main), deklarace v blocích jsou lokální, proměnné mimo blok neexistují, lokální proměnné zastíní globální proměnné stejného jména, bloky mohou být vnořeny do bloku. L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 7/51

Globální a lokální deklarace #include <stdio.h> int x = 1, y = 2; /* globální proměnné */ void fun ( void ) { int a = 1; printf ( "fun(): x=%d y=%d a=%d\n", x, y, a ); int main ( void ) { int x = 10; /* lokální x zastíní globální x */ int a = 20; fun ( ); printf ( "main ( ): x=%d y=%d a=%d\n", x, y, a ); return 0; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 8/51

Příkaz if if příkaz má dvě různé formy: if ( podmínka ) příkaz if ( podmínka ) příkaz1 else příkaz2 podmínka je výraz: nula znamená false, nenula true. příklad jak vypočíst minimum dvou proměnných x a y. if ( x < y ) /* if-then-else */ min = x; else min = y; printf ( "Min = %d\n", min ); min = x; /* nebo alternativně, jen if-then */ if ( y < x ) min = y; printf ( "Min = %d\n", min ); L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 9/51

Příkaz if Když má být proveden víc než jeden příkaz v podmíněné větvi, je třeba použít blok. Příklad: dány dvě proměnné, jejichž hodnoty je třeba případně zaměnit tak, aby x nebylo větší než y: if ( x > y ) { tmp = x; x = y; y = tmp; Špatné řešení: if ( x > y ) tmp = x; /* větev - pouze tento příkaz */ x = y; y = tmp; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 10/51

Příkaz if Dány dvě proměnné x a y, vypočíst max a min. if ( x < y ) { min = x; max = y; else { min = y; max = x; Špatné řešení: if ( x < y ) min = x; max = y; else /* chyba syntaxe: neočekávaný else */ min = y; max = x; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 11/51

Příkaz if Jakýkoli příkaz může být vnořen ve větvi if. Tudíž příkaz if lze vnořit do jiného if. Příklad: dána proměnná x, vypočíst znaménko (-1,0,1): if ( x < 0 ) s = -1; else if ( x == 0 ) s = 0; else s = 1; Dány tři proměnné x, y a z, vypočíst maximum: if ( x > y ) if ( x > z ) max = x; else max = z; else if ( y > z ) max = y; else max = z; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 12/51

Příkaz if Jakýkoli příkaz může být vnořen ve větvi if. Tudíž příkaz if lze vnořit do jiného if. Příklad: dána proměnná x, vypočíst znaménko (-1,0,1): if ( x < 0 ) s = -1; else if ( x == 0 ) s = 0; else s = 1; Dány tři proměnné x, y a z, vypočíst maximum: if ( x > y ) if ( x > z ) max = x; else max = z; else if ( y > z ) max = y; else max = z; Uvedené zápisy jsou syntakticky správné, kompilátor jim bude rozumět. Pro člověka jsou ale obtížně čitelné. Vhodné formátování zdrojového kódu usnadňuje jeho porozumění. Důležité je zejména zarovnávat bloky. L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 12/51

Příkaz if Příklad: dána proměnná x, vypočíst znaménko (-1,0,1): if ( x < 0 ) s = -1; else if ( x == 0 ) s = 0; else s = 1; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 13/51

Příkaz if Dány tři proměnné x, y a z, vypočíst maximum: if ( x > y ) if ( x > z ) max = x; else max = z; else if ( y > z ) max = y; else max = z; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 14/51

Příkaz if Najít druhé maximum... pro dvě proměnné a a b: if ( a > b ) max2 = b; else max2 = a; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 15/51

Příkaz if Najít druhé maximum... pro dvě proměnné a a b: if ( a > b ) max2 = b; else max2 = a; pro tři proměnné a, b a c: if ( a > b && b > c ) max2 = b; else if ( a < b && b < c ) max2 = b; else if ( a > c && c > b ) max2 = c; else if ( a < c && c < b ) max2 = c; else if ( b > a && a > c ) max2 = a; else max2 = a; /* 3! = 6 kombinací */ L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 15/51

Příkaz if Najít druhé maximum... pro dvě proměnné a a b: if ( a > b ) max2 = b; else max2 = a; pro tři proměnné a, b a c: if ( a > b && b > c ) max2 = b; else if ( a < b && b < c ) max2 = b; else if ( a > c && c > b ) max2 = c; else if ( a < c && c < b ) max2 = c; else if ( b > a && a > c ) max2 = a; else max2 = a; /* 3! = 6 kombinací */ pro čtyři proměnné a, b, c a d: if ( a > b && b > c && c > d ) max2 = b; else... /* 4! = 24 kombinací */... a co, když hodnoty nejsou navzájem různé. L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 15/51

Příkaz if Nalezení druhého maxima lépe: mějme dvě proměnné: max1 (maximum) a max2 (druhé maximum), inicializace proměnných, nastavit na 0? L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 16/51

Příkaz if Nalezení druhého maxima lépe: mějme dvě proměnné: max1 (maximum) a max2 (druhé maximum), inicializace proměnných, nastavit na 0? NE: -10, -9, -8 nastavit na první přečtenou hodnotu? L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 16/51

Příkaz if Nalezení druhého maxima lépe: mějme dvě proměnné: max1 (maximum) a max2 (druhé maximum), inicializace proměnných, nastavit na 0? NE: -10, -9, -8 nastavit na první přečtenou hodnotu? NE: 10, 9, 8 nastavit na první a druhou hodnotu? L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 16/51

Příkaz if Nalezení druhého maxima lépe: mějme dvě proměnné: max1 (maximum) a max2 (druhé maximum), inicializace proměnných, nastavit na 0? NE: -10, -9, -8 nastavit na první přečtenou hodnotu? NE: 10, 9, 8 nastavit na první a druhou hodnotu? ANO max1 = a > b? a : b; max2 = a < b? a : b; číst další hodnoty (v cyklu): if ( x > max1 ) { max2 = max1; max1 = x; else if ( x > max2 ) max2 = x; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 16/51

Příkaz if - i > 0 - + i < 20 + j = 1 j = 8 if ( i > 0 ) if ( i < 20 ) j = 8; else j = 1; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 17/51

Příkaz if - i > 0 - + i < 20 + j = 1 j = 8 if ( i > 0 ) if ( i < 20 ) j = 8; else j = 1; Špatně, např.: i=-4 L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 17/51

Příkaz if - i > 0 - + i < 20 + j = 1 j = 8 if ( i > 0 ) { if ( i < 20 ) j = 8; else j = 1; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 18/51

Příkaz if přestupný rok Země oběhne Slunce za přibližně 365,24219 dne (tropický rok). Rozdíl mezi délkou tropického roku a 365 dny kalendáře kompenzují přestupné roky. Juliánský kalendář (podle Julia Gaia Caesara) vkládal přestupný rok 1x za 4 roky (rok děitelný 4). Průměrná délka Juliánského kalendářního roku je 365,25 dne. V roce 1582 provedl papež Řehoř XIII reformu (Gregoriánský kalendář): pokud je rok dělitelný 400, je přestupný (1600, 2000,... ), jinak, pokud je rok dělitelný 100, není přestupný (1900, 2100,... ), jinak, pokud je rok dělitelný 4, je přestupný (2004, 2008,... ), jinak není přestupný (2001, 2002,... ). Průměrná délka Gregoriánského kalendářního roku je 365,2425 dne, tedy okolo roku 4000 bude potřeba další změna kalendáře. L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 19/51

Příkaz if přestupný rok Přechod na Gregoriánský kalendář znamenal přeskočit v kalendáři cca 11 dní + 0.75 dne za každých 100 let zpoždění. V různých zemích byl Gregoriánský kalendář zaveden různě: v Čechách a ve Slezsku od ledna 1584, na Moravě od října 1584, v USA od září 1752, L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 20/51

Příkaz if přestupný rok Přechod na Gregoriánský kalendář znamenal přeskočit v kalendáři cca 11 dní + 0.75 dne za každých 100 let zpoždění. V různých zemích byl Gregoriánský kalendář zaveden různě: v Čechách a ve Slezsku od ledna 1584, na Moravě od října 1584, v USA od září 1752, v Rusku od února 1918, L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 20/51

Příkaz if přestupný rok Přechod na Gregoriánský kalendář znamenal přeskočit v kalendáři cca 11 dní + 0.75 dne za každých 100 let zpoždění. V různých zemích byl Gregoriánský kalendář zaveden různě: v Čechách a ve Slezsku od ledna 1584, na Moravě od října 1584, v USA od září 1752, v Rusku od února 1918, v Řecku od roku 1923 a v Turecku od let 1926/1927. Kuriozity: Češi měli v roce 1584 Velikonoce o 4 týdny dříve než na Moravě (proč o 4 týdny?), v Holandsku neměli v roce 1582 Vánoce, Švédsko chtělo přecházet na nový kalendář plynule 40 let, v Rusku byla říjnová revoluce v listopadu, pravoslavné církve se stále řídí Juliánským kalendářem. L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 20/51

Příkaz if přestupný rok #include <stdio.h> #include <stdlib.h> int main ( void ) { int year; printf("zadej rok:"); scanf("%d", &year ); printf("rok %d ", year ); if ( year % 4 == 0 && ( year % 100!= 0 year % 400 == 0 ) ) printf("je prestupny\n"); else printf("neni prestupny\n"); return 0; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 21/51

Příkaz if a efektivita Dána proměnná x, jejíž hodnota je v intervalu 0..99999. Chceme určit počet dekadických cifer. Řešení #1: if ( x < 10 ) digits = 1; else if ( x < 100 ) digits = 2; else if ( x < 1000 ) digits = 3; else if ( x < 10000 ) digits = 4; else digits = 5; Řešení #2: if ( x >= 10000 ) digits = 5; else if ( x >= 1000 ) digits = 4; else if ( x >= 100 ) digits = 3; else if ( x >= 10 ) digits = 2; else digits = 1; Které řešení je lepší? L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 22/51

Příkaz if a efektivita Předpokládejme rovnoměrné rozdělení hodnot x z intervalu 0..99999 a uvažujme 100000 běhů programu. Řešení #1 provede: rozsah běhů porovnání 0 9 10 1 10 99 90 2 100 999 900 3 1000 99999 99000 4 celkem 100000 398890 3.99 porovnání/běh Řešení #2 provede: rozsah běhů porovnání 99999 10000 90000 1 9999 1000 9000 2 999 100 900 3 99 0 100 4 celkem 100000 111100 1.11 porovnání/běh L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 23/51

Příkaz if a efektivita Předpokládejme, že hodnoty x nejsou rozděleny rovnoměrně v intervalu 0..99999, ale například mají Poissonovo rozdělení. Řešení #1 provede: rozsah běhů porovnání 0 9 50000 1 10 99 25000 2 100 999 12500 3 1000 99999 12500 4 celkem 100000 187500, 1.88 porovnání/běh Řešení #2 provede: rozsah běhů porovnání 99999 10000 6250 1 9999 1000 6250 2 999 100 12500 3 99 0 75000 4 celkem 100000 356250, 3.56 porovnání/běh L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 24/51

Příkaz if a efektivita Řešení #2 je skoro čtyřikrát rychlejší (pro rovnoměrné rozdělení), nebo skoro dvakrát pomalejší (Poissonovo rozdělení). Obě řešení jsou špatná z hlediska programování (zdlouhavá, jen pro omezený rozsah hodnot). Celý rozsah nezáporných celých čísel pokrývá řešení: digits = x? (int) log10 ( x ) + 1 : 1; Jednodušší na pochopení je řešení s cyklem while: digits = 1; while ( x >= 10 ) { x /= 10; digits ++; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 25/51

Příkaz while Příkaz while má formu: while ( podmínka ) příkaz Příklad: q = x; while ( q >= y ) q -= y; Co je výsledkem tohoto fragmentu kódu? Poznámka: tělo cyklu se nemusí vůbec vykonat. L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 26/51

Příkaz while Dva nebo více příkazů v těle cyklu musí být obklopeno složenými závorkami (blok): Příklad: q = x; p = 0; while ( q >= y ) { q -= y; p ++; Co je výsledkem tohoto fragmentu kódu? L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 27/51

Příkaz while Příklad: výpočet faktoriálu: #include <stdio.h> int main ( void ) { int i = 1, f = 1, n; printf ( "Napis prirozene cislo:\n" ); scanf ( "%d", &n ); while ( i < n ) { i = i + 1; f = f * i; printf ( "%d! = %d\n", n, f ); return 0; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 28/51

Příkaz do-while Cyklus do-while je podobný cyklu while. Liší se tím, že podmínka je testována až po vykonání příkazu(ů) v těle cyklu. Příkaz do-while má formu: do statement while ( podmínka ); Příkad faktoriálu: f = 1; i = 0; do { i = i + 1; f = f * i; while ( i < n ); Poznámka: tělo cyklu se vykoná nejméně jednou. L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 29/51

Příkaz for Cykly bývají často řízeny proměnnou, přičemž je známo: jaká je počáteční hodnota proměnné, jaká je podmínka ukončení cyklu, jak se má měnit hodnota proměnné po každé iteraci. Příklad (faktoriál): f = 1; i = 1; while ( i <= n ) { f = f * i; i = i + 1; Cyklus z předchozího příkladu může být přepsán: f = 1; for ( i = 1; i <= n; i ++ ) f *= i; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 30/51

Příkaz for Příkaz for má for obecnou formu: for ( inicializace ; podmínka pokračování cyklu ; změna řídící proměnné ) příkaz Tato syntaxe může být přepsána do formy ekvivalentního cyklu while: inicializace; while ( podmínka pokračování cyklu ) { příkaz; změna řídící proměnné; Nejčastěji je změna řídící proměnné ve tvaru i ++ nebo i --. L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 31/51

Zpracování sekvencí dat Problém: sečíst čísla ze standardního vstupu. Princip řešení: sum = 0; while ( jsou čísla na vstupu ) { přečíst další číslo; sum += number; Jak zjistit konec vstupu: pevný počet čísel v sekvenci, počet čísel sekvence je dán hodnotou přečtenou před sekvencí, sekvence je zakončena zarážkou (sentinel) zvláštní hodnota, EOF,.... L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 32/51

Zpracování sekvencí dat Pevný počet čísel (5 čísel): a 1 a 2 a 3 a 4 a 5 #include <stdio.h> int main ( void ) { int x, sum = 0, i; printf ( "Napis 5 cisel\n" ); for ( i = 0; i < 5; i ++ ) { scanf ( "%d", &x ); sum += x; printf ( "soucet je %d\n", sum ); return 0; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 33/51

Zpracování sekvencí dat Pevný počet čísel (5 čísel): a 1 a 2 a 3 a 4 a 5 #include <stdio.h> int main ( void ) { int x, sum = 0, i; printf ( "Napis 5 cisel\n" ); for ( i = 0; i < 5; i ++ ) { scanf ( "%d", &x ); sum += x; printf ( "soucet je %d\n", sum ); return 0; Jak změnit počet čísel (např. na 6)? L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 33/51

Zpracování sekvencí dat Pevný počet čísel (5 čísel): a 1 a 2 a 3 a 4 a 5 #include <stdio.h> #define INPUT_LENGTH 5 /* žádný středník po #define */ int main ( void ) { int x, sum = 0, i; printf ( "Napis %d cisel\n", INPUT_LENGTH ); for ( i = 0; i < INPUT_LENGTH; i ++ ) { scanf ( "%d", &x ); sum += x; printf ( "soucet je %d\n", sum ); return 0; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 34/51

Zpracování sekvencí dat Počet dat v sekvenci je dán prvým číslem: n a 1 a 2... a n #include <stdio.h> int main ( void ) { int x, sum = 0, i, n; printf ( "Napis pocet dat v sekvenci\n" ); scanf ( "%d", &n ); for ( i = 0; i < n; i ++ ) { scanf ( "%d", &x ); sum += x; printf ( "soucet je %d\n", sum ); return 0; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 35/51

Zpracování sekvencí dat Sekvence je zakončena zarážkou (hodnota 0): a 1 a 2... 0, a i 0 #include <stdio.h> int main ( void ) { int x, sum = 0; scanf ( "%d", &x ); while ( x ) { sum += x; scanf ( "%d", &x ); printf ( "soucet je %d\n", sum ); return 0; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 36/51

Zpracování sekvencí dat Sekvence je zakončena zarážkou (EOF): a 1 a 2... a n #include <stdio.h> int main ( void ) { int x, sum = 0; while ( scanf ( "%d", &x ) == 1 ) sum += x; if ( feof ( stdin ) ) printf ( "soucet je %d\n", sum ); else... /* špatný vstup - chyba zpracování */ return 0; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 37/51

break a continue Cykly for a while mohou být zakončeny před vstupem do těla cyklu, cyklus do-while může být zakončen po opuštění těla cyklu, je-li třeba zakončit cyklus uvnitř těla cyklu (např. při zjištění chyby), použije se příkaz break: while ( cond1 ) {... if ( cond2 ) break;... příkaz continue startuje novou iteraci těla cyklu. Příklad: zobrazit čísla z intervalu 1..100 kromě násobků 10: for ( i = 1; i <= 100; i ++ ) { if ( i % 10 == 0 ) continue; printf ( "%d\n", i ); L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 38/51

Konečné a nekonečné cykly Algoritmy jsou konečné, tedy cykly musí skončit. Nekonečný cyklus patří k nejčastějším chybám. Hodnota(y) proměnné(ých) podmínky opakování cyklu se musí v těle cyklu měnit: když se hodnoty proměnných v těle cyklu mění, cyklus může skončit, když se hodnoty proměnných v těle cyklu nemění, iterace bud nikdy nenastane, nebo se bude iterovat stále. Triviální příklady: while ( i > 0 ) j = i - 1; double x = 0; int i = -1; while ( i < 0 ) { x = x + sin ( i * 0.6 ); i --; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 39/51

Konečné a nekonečné cykly int i =..., n =...; while ( i!= n ) {...; /* nemění se ani i ani n */ i ++; Co musí splňovat i a n, aby se cyklus ukončil? L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 40/51

Konečné a nekonečné cykly int i =..., n =...; while ( i!= n ) {...; /* nemění se ani i ani n */ i ++; Co musí splňovat i a n, aby se cyklus ukončil? Zřejmě se ukončí pokud i <= n. Ukončí se cyklus pro i > n? L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 40/51

Konečné a nekonečné cykly int i =..., n =...; while ( i!= n ) {...; /* nemění se ani i ani n */ i ++; Co musí splňovat i a n, aby se cyklus ukončil? Zřejmě se ukončí pokud i <= n. Ukončí se cyklus pro i > n? Uplatní se případně přetečení rozsahu? Změní se něco, pokud i a n budou typu double? L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 40/51

Konečné a nekonečné cykly int i =..., n =...; while ( i!= n ) {...; /* nemění se ani i ani n */ i ++; Co musí splňovat i a n, aby se cyklus ukončil? Zřejmě se ukončí pokud i <= n. Ukončí se cyklus pro i > n? Uplatní se případně přetečení rozsahu? Změní se něco, pokud i a n budou typu double? Podmínky konečnosti cyklu lze určit téměř vždy (někdy to je velmi obtížné). Konečnost cyklu musí zajistit kontroly předcházející cyklu. Zabezpečený program musí kontrolovat přípustnost vstupních dat. L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 40/51

Konečné a nekonečné cykly problém 3x + 1 Problém 3x + 1 (Syrakuský problém, Collatzův problém): int n =...; while ( n!= 1 ) { if ( n % 2 == 0 ) n /= 2; else n = 3 * n + 1; n=6 : 6, 3, 10, 5, 16, 8, 4, 2, 1 n=27 : 27, 82, 41, 124, 62, 31, 94, 47, 142, 71, 214, 107, 322, 161, 484, 242,..., 9232,..., 4, 2, 1 (111 iterací) Otázka: zastaví se tento cyklus pro libovolné n? http://fyzmatik.pise.cz/112549-collatzuv-problem.html L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 41/51

Programujeme cykly efektivně Příklad zjištění, zda x je prvočíslo: int x =..., isprime = 1, i; for ( i = 2; i <= (int) sqrt ( x ); i ++ ) { if ( x % i == 0 ) isprime = 0; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 42/51

Programujeme cykly efektivně Příklad zjištění, zda x je prvočíslo: int x =..., isprime = 1, i; for ( i = 2; i <= (int) sqrt ( x ); i ++ ) { if ( x % i == 0 ) isprime = 0; Při nalezení prvního dělitele je zbytečné pokračovat ve zkoušení dalších hodnot. L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 42/51

Programujeme cykly efektivně Příklad zjištění, zda x je prvočíslo: int x =..., isprime = 1, i; for ( i = 2; i <= (int) sqrt ( x ); i++ ) { if ( x % i == 0 ) { isprime = 0; break; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 43/51

Programujeme cykly efektivně Příklad zjištění, zda x je prvočíslo: int x =..., isprime = 1, i; for ( i = 2; i <= (int) sqrt ( x ); i++ ) { if ( x % i == 0 ) { isprime = 0; break; Výraz (int)sqrt(x) je počítán v každém cyklu, i když se jeho hodnota nemění. Optimalizující kompilátor to pozná, hloupý kompilátor k tomu donutíme: int max = (int) sqrt ( x ); for ( i = 2; i <= max; i ++ )... L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 43/51

Metoda shozeného praporku Testování jedné podmínky pro všechny prvky dané sekvence (všechna sudá, všechna kladná čísla lichá,... ). Nastav praporek indikující splnění podmínky na hodnotu true (1). Procházej sekvenci a pro každý prvek ověř, že je podmínka stále splněna: pokud není splněna, shod praporek, pokud je splněna, nic nedělej. L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 44/51

Metoda shozeného praporku Test, zda jsou na vstupu pouze sudá čísla: int x, alleven = 1; /* flag is set */ printf("zadej cisla, 0=konec.\n"); do { scanf("%d", &x); if ( x % 2 == 1 ) alleven = 0; else alleven = 1; while ( x!= 0 ); if ( alleven ) printf("vsechna suda\n"); else printf("alespon jedno liche\n"); L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 45/51

Metoda shozeného praporku Test, zda jsou na vstupu pouze sudá čísla: int x, alleven = 1; /* flag is set */ printf("zadej cisla, 0=konec.\n"); do { scanf("%d", &x); if ( x % 2 == 1 ) alleven = 0; else alleven = 1; /* do not restore! */ while ( x!= 0 ); if ( alleven ) printf("vsechna suda\n"); else printf("alespon jedno liche\n"); Nefunguje pro vstup 2 3 4 0 L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 45/51

Metoda shozeného praporku Test, zda jsou na vstupu pouze sudá čísla:... int x, alleven = 1; /* flag is set */ printf("zadej cisla, 0=konec.\n"); do { scanf("%d", &x); if ( x % 2 == 1 ) alleven = 0; while ( x!= 0 ); if ( alleven ) printf("vsechna suda\n"); else printf("alespon jedno liche\n"); L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 46/51

Metoda shozeného praporku Test, zda jsou na vstupu pouze sudá čísla:... int x, alleven = 1; /* flag is set */ printf("zadej cisla, 0=konec.\n"); do { scanf("%d", &x); if ( x % 2 == 1 ) /* -1 % 2 = -1 */ alleven = 0; while ( x!= 0 ); if ( alleven ) printf("vsechna suda\n"); else printf("alespon jedno liche\n"); Nefunguje pro vstup 2-1 4 0 L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 46/51

Metoda shozeného praporku Test, zda jsou na vstupu pouze sudá čísla:... int x, alleven = 1; /* flag is set */ printf("zadej cisla, 0=konec.\n"); do { scanf("%d", &x); if ( x % 2!= 0 ) alleven = 0; while ( x!= 0 ); if ( alleven ) printf("vsechna suda\n"); else printf("alespon jedno liche\n"); L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 47/51

Příkaz switch Příkaz switch umožňuje větvení programu na několik větví. Větve jsou identifikovány celočíselnými konstantami. Příkaz switch má obecně tvar: switch ( výraz ) { case const1: příkaz1 break; case const2: příkaz2 break;... case constn: příkazn break; default: příkaz L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 48/51

Příkaz switch Příkaz break dynamicky zakončuje větev: switch ( n ) { case 1: printf ( ""*"" ); break; case 2: printf ( ""**"" ); break; case 3: printf ( ""***"" ); break; default: printf ( ""---"" ); Když break chybí, pokračuje se další větví (dokud se nedojde příkaz break nebo na konec příkazu switch): switch ( n ) { case 1: printf ( ""*"" ); /* n==1: ******--- */ case 2: printf ( ""**"" ); case 3: printf ( ""***"" ); default: printf ( ""---"" ); L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 49/51

Příkaz switch počet dní od počátku roku #include <stdio.h> int main ( void ) { int d, m, y, n = 0; printf ( ""Napis den mesic a rok:\n"" ); scanf ( "%d%d%d", &d, &m, &y ); switch ( m ) { case 1: n = d; break; case 2: n = 31 + d; break; case 3: n = 59 + d; break;... case 12: n = 334 + d; break; default: printf ( "Spatny mesic.\n" ); /*... korekce na přestupný rok... */ printf ( "%d dni od pocatku roku.\n", n ); return 0; L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 50/51

Otázky a odpovědi Otázky... L. Vagner, J. Vogel, ČVUT FIT Příkazy, BI-PA1 51/51