Funkce, procedury, složitost

Podobné dokumenty
Funkce, intuitivní chápání složitosti

8 Třídy, objekty, metody, předávání argumentů metod

Ukazatele #1, struktury

Struktura programu v době běhu

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

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

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

Vyučovací hodina. 1vyučovací hodina: 2vyučovací hodiny: Opakování z minulé hodiny. Procvičení nové látky

Ukazatel (Pointer) jako datový typ - proměnné jsou umístěny v paměti na určitém místě (adrese) a zabírají určitý prostor (počet bytů), který je daný

Obsah přednášky 7. Základy programování (IZAPR) Přednáška 7. Parametry metod. Parametry, argumenty. Parametry metod.

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:

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

Abstraktní třídy, polymorfní struktury

Algoritmizace a programování

int ii char [16] double dd název adresa / proměnná N = nevyužito xxx xxx xxx N xxx xxx N xxx N

Pointery II. Jan Hnilica Počítačové modelování 17

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

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

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

PB161 Programování v jazyce C++ Přednáška 4

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

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

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

Úvod do programovacích jazyků (Java)

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

Více o konstruktorech a destruktorech

Správné vytvoření a otevření textového souboru pro čtení a zápis představuje

Rekurzivní algoritmy

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

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

IUJCE 07/08 Přednáška č. 6

2 Datové typy v jazyce C

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

Konstruktory a destruktory

Ukazatele #2, dynamická alokace paměti

Abstraktní datové typy, moduly

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

přetížení operátorů (o)

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

Program převod z desítkové na dvojkovou soustavu: /* Prevod desitkove na binarni */ #include <stdio.h>

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

4. Rekurze. BI-EP1 Efektivní programování Martin Kačer

PŘETĚŽOVÁNÍ OPERÁTORŮ

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

Programování v jazyce C a C++

PODOBÁ SE JAZYKU C S NĚKTERÝMI OMEZENÍMI GLOBÁLNÍ PROMĚNNÉ. NSWI162: Sémantika programů 2

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

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

Sdílení dat mezi podprogramy

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

Objektově orientované programování

Dekompozice problému, rekurze

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

Úvod do programování. Lekce 5

Programovací jazyk Pascal

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

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í

ZPRO v "C" Ing. Vít Hanousek. verze 0.3

Základní datové struktury

IUJCE 07/08 Přednáška č. 1

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

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

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

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

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

Odvozené a strukturované typy dat

Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody

Základy algoritmizace a programování

Základy programování (IZP)

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Mělká a hluboká kopie

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

Algoritmizace a programování

Datové struktury. alg12 1

NPRG030 Programování I, 2015/16 1 / :25:32

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

IAJCE Přednáška č. 6. logický celek, řešící dílčí část problému Příklad velmi špatného zápisu programu na výpočet obsahu obdélníku

- dělají se také pomocí #define - podobné (použitím) funkcím - předpřipravená jsou např. v ctype.h. - jak na vlastní makro:

Základy programování (IZP)

Lekce 6 IMPLEMENTACE OPERAČNÍHO SYSTÉMU LINUX DO VÝUKY INFORMAČNÍCH TECHNOLOGIÍ JAZYK C

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

Spojová implementace lineárních datových struktur

Úvod do programování. Lekce 1

Maturitní otázky z předmětu PROGRAMOVÁNÍ

Pole stručný úvod do začátku, podrobně později - zatím statická pole (ne dynamicky) - číslují se od 0

Rozklad problému na podproblémy, rekurze

Lineární spojový seznam (úvod do dynamických datových struktur)

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.

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

Řídicí struktury. alg3 1

Algoritmizace a programování

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

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

Testování prvočíselnosti

NPRG031 Programování II --- 2/2 Z, Zk

Rekurze. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

Ukazatele, dynamická alokace

IUJCE 07/08 Přednáška č. 4. v paměti neexistuje. v paměti existuje

Transkript:

Funkce, procedury, složitost BI-PA1 Programování a Algoritmizace 1 Miroslav Baĺık, Ladislav Vagner a 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 31. října 2017 a 2. a 3. listopadu 2017

Obsah Funkce. Parametry. Deklarace a definice. Procedury. Výstupní parametry. Složitost (intuitivně). M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 2/48

Funkce faktoriál #include <stdio.h> int main ( void ) { int n, i = 1, f = 1; /* ------- čtení vstupu ------- */ printf ( "Napis prirozene cislo:\n" ); scanf ( "%d", &n ); if ( n<1 ) { printf ( "%d neni prirozene cislo\n", n ); return 1; /* ------- výpočet faktoriálu ------- */ while ( i<n ) { i = i + 1; f = f * i; printf ( "%d! = %d\n", n, f ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 3/48

Funkce faktoriál int readnumber ( void ) { int n; printf ( "Napis prirozene cislo:\n" ); scanf ( "%d", &n ); if ( n < 1 ) { printf ( "%d neni prirozene cislo\n", n ); exit ( 1 ); /* to by mohlo být uděláno lépe */ return n; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 4/48

Funkce faktoriál Funkce readnumber() čte přirozené číslo ze standardního vstupu. int readnumber ( void ) je prototyp funkce (hlavička, signatura): funkce nemá žádné parametry (void seznam parametrů), jméno funkce je readnumber, funkce vrací návratovou hodnotu typu int. return n; příkaz končící zpracování funkce (návrat do volající funkce). Návratová hodnota je hodnota n. Pokud kompilátor zná hlavičku funkce, je možno funkci zavolat: int x = readnumber (); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 5/48

Funkce faktoriál int factorial ( int n ) { int i = 1, f = 1; while ( i<n ) { i = i+1; f = f*i; return f; Funkce factorial() má jeden parametr n a vrací hodnotu typu int. Příklad volání funkce: int y = factorial ( 10 ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 6/48

Funkce faktoriál /*... volání funkcí readnumber() a factorial() */ int main ( void ) { int x = readnumber (); printf ( "%d! = %d\n", x, factorial(x) ); return 0 ; Funkce main () je krátká, jednoduchá a snadno pochopitelná. Proměnné i a f v main ( ) už nejsou třeba. Jsou-li zachovány funkční prototypy, funkce mohou být vylepšovány (zrychlení výpočtu, bezpečnější,... ) bez přepsání zbytku programu. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 7/48

Funkce faktoriál int readnumber ( void ) { int n; printf("napis prirozene cislo:\n"); if ( scanf ( "%d", &n )!= 1 ) { printf ( "Spatny vstupni format.\n" ); exit ( 1 ); if ( n<1 ) { printf ( "%d neni prirozene cislo\n", n ); exit ( 1 ); /* to by mohlo být uděláno lépe */ return n; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 8/48

Odbočka proč je exit() špatně Funkce exit() je zamýšlena jako havarijní ukončení programu za podmínek, kdy další běh programu nemá cenu a může vést k dalším problémům (např. při poruše HW, který je programem řízen). Použití exit() jako reakce na nesprávný vstup je zbrklé. Chyba vstupu nemusí nutně znamenat konec programu: uživatel může být vyzván k opravě, vstupní údaj nemusí být povinný, v programu (v dalších vláknech) může probíhat důležitý výpočet, může být potřeba uložit stav výpočtu před ukončením,... Obecně, dílčí funkce (jako např. zde readnumber) nezná celkový obraz programu, aby mohla rozhodnout, zda se lze z chyby zotavit. O tom zpravidla rozhodují jiné vrstvy programu (volající). Proto bývá lepší chybu oznámit volajícímu (zde např. úpravou rozhraní funkce nebo výjimkou v C++). M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 9/48

Funkce definice Funkce je podprogram řešící dílčí problém a vracející hodnotu. Definice funkce: hlavička_funkce tělo_funkce hlavička funkce v C/C++ má obecný tvar: typ jméno ( seznam parametrů ) typ je návratový typ funkce, jméno je identifikátor funkce, seznam parametrů seznam formálních parametrů, každý ve tvaru typ jméno, parametry jsou odděleny čárkou. Funkce bez parametrů používají místo seznamu parametrů kĺıčové slovo void. Tělo funkce je blok, jež je proveden, když je funkce zavolána. Funkce se vrací do volající funkce po provedení příkazu return výraz. Hodnota výrazu je výsledek předaný volající funkci. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 10/48

Funkce parametry Parametry funkce (formální parametry) jsou lokální proměnné této funkce. Před vlastním zavoláním funkce jsou výrazy reprezentující skutečné parametry vyhodnoceny a tyto hodnoty vytvoří počáteční hodnoty formálních parametrů. Při předání parametrů se mohou provádět typové konverze, jako při regulérním přiřazení. Pořadí vyhodnocení parametrů není normou definováno. #include <stdio.h> int max(int x, int y) { if (x > y) return x; return y; int main ( void ) { int a = 9, b = 20, x = 100; printf ( "%d\n", max( a, b - a ) ); printf ( "%d\n", max( 32.4, b )) ; printf ( "%d\n", x ); /* 100, nemodifikováno */ printf ( "%d, %d\n", a ++, a); /* 10, 9 nebo 10!!! */ M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 11/48

Funkce parametry Formální parametr funkce je při volání naplněn hodnotou skutečného parametru. Je chybou přepsat tuto hodnotu hodnotou přečtenou ze vstupu (obvyklá začátečnická chyba). int max ( int x, int y ) { scanf ( "%d %d", &x, &y ); /* zde nesmysl */ /* x a y jsou parametry, tedy už žádné volání scanf! Pokud by x a y mělo být čteno z klávesnice, tak by to neměly být parametry funkce. */ if ( x > y ) return x; return y; Poznámka: Výše uvedený kód funkce max () je formálně správný (nebot hodnoty formálních parametrů je možno ve funkci měnit), ale zde je nesmyslný. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 12/48

Funkce deklarace Deklarace funkce je hlavička funkce následovaná středníkem. Deklarované funkce mohou být použity v programu (tj. volány). Definice funkce (tělo funkce) může být dodáno později z jiného modulu nebo z knihovny. Hlavičkové soubory obsahují deklarace knihovních funkcí. #include <stdio.h> int max (int x, int y ); /* deklarace */ int main ( void ) { int a = 10, b = 20; printf ( "%d\n", max(a, b) ); /* OK, lze použít */ int max ( int x, int y ) { /* definice */ if ( x > y ) return x; return y; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 13/48

Funkce deklarace Jaké deklarace jsou v C správné int foo ( void ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 14/48

Funkce deklarace Jaké deklarace jsou v C správné int foo ( void ); Ok. void 2foo (int p); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 14/48

Funkce deklarace Jaké deklarace jsou v C správné int foo ( void ); Ok. void 2foo (int p); Špatně, identifikátor funkce nesmí začínat číslicí. void foo (int p, q; double r); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 14/48

Funkce deklarace Jaké deklarace jsou v C správné int foo ( void ); Ok. void 2foo (int p); Špatně, identifikátor funkce nesmí začínat číslicí. void foo (int p, q; double r); Špatně, typ musí být uveden pro každý parametr zvlášt. void foo ( p, q, r, s ) int p,r; double q,s;... M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 14/48

Funkce deklarace Jaké deklarace jsou v C správné int foo ( void ); Ok. void 2foo (int p); Špatně, identifikátor funkce nesmí začínat číslicí. void foo (int p, q; double r); Špatně, typ musí být uveden pro každý parametr zvlášt. void foo ( p, q, r, s ) int p,r; double q,s;... Špatně, toto je zápis hlavičky funkce v původní Kernighan & Ritchie notaci. Tento zápis není kompatibilní s ANSI C ani s C++. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 14/48

Funkce deklarace Jaké deklarace jsou v C správné int foo (); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 15/48

Funkce deklarace Jaké deklarace jsou v C správné int foo (); Ok, ale v ANSI C znamená, že funkce má nějaké bĺıže neurčené parametry. V C++ znamená, že funkce nemá žádné parametry. Pokud chceme kompatibilitu pro C i C++, je lepší explicitně vypsat void. foo (int p); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 15/48

Funkce deklarace Jaké deklarace jsou v C správné int foo (); Ok, ale v ANSI C znamená, že funkce má nějaké bĺıže neurčené parametry. V C++ znamená, že funkce nemá žádné parametry. Pokud chceme kompatibilitu pro C i C++, je lepší explicitně vypsat void. foo (int p); Ok, v C je návratový typ implicitně int. V C++ správně není. Z důvodu kompatibility raději nepoužívat. int foo (int, char **, int (*(*)(int (*)[3]))(void)); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 15/48

Funkce deklarace Jaké deklarace jsou v C správné int foo (); Ok, ale v ANSI C znamená, že funkce má nějaké bĺıže neurčené parametry. V C++ znamená, že funkce nemá žádné parametry. Pokud chceme kompatibilitu pro C i C++, je lepší explicitně vypsat void. foo (int p); Ok, v C je návratový typ implicitně int. V C++ správně není. Z důvodu kompatibility raději nepoužívat. int foo (int, char **, int (*(*)(int (*)[3]))(void)); Ok, v C i C++ lze v deklaraci vynechat názvy parametrů. Ale je lepší názvy parametrů vypsat, aby byl zřejmý jejich význam. Pokud vás tato ukázka nepřesvědčila, podívejte se do hlavičkových souborů OpenSSL (a případně je zkuste použít). M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 15/48

Funkce volání Funkce foo() muže být volána z funkce bar(), je-li je znám prototyp funkce foo(). To znamená: bud je definice foo() před bar() anebo je deklarace foo() před bar(). Funkce foo() s n formálními parametry je volána: foo (p1, p2, p3,..., pn ) Skutečné parametry (výrazy) jsou vyhodnoceny a zkopírovány do formálních parametrů. Pořadí parametrů je důležité pro správné spárování. Návratová hodnota je předána příkazem return výraz. Funkce jsou obvykle volány ve výrazech. Je-li je funkce volána jako samostatný příkaz, návratová hodnota je tiše zahozena. x = foo(1,2,3) + 4; /* návratová hodnota použita */ foo(1,2,3); /* návratová hodnota zahozena */ M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 16/48

Funkce příklady #include <stdio.h> /* --- Přestupný rok 1 --- */ int leapyear ( int y ) { if ( y % 4 == 0 && ( y % 100!= 0 y % 400 == 0 )) return 1; int main ( void ) { int y; printf ( "Napis rok:\n" ); scanf ( "%d", &y ); printf ( "Rok %d ", y ); if ( leapyear( y ) ) printf ( "je prestupny rok.\n" ); else printf ( "neni prestupny rok.\n" ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 17/48

Funkce příklady #include <stdio.h> /* --- Přestupný rok 2 --- */ int leapyear (int y) { return ( y % 4 == 0 && ( y % 100!= 0 y % 400 == 0 )); int main ( void ) { int y; printf ( "Napis rok:\n" ); scanf ( "%d", &y ); printf ( "Rok %d ", y ); if ( leapyear( y ) ) printf ( "je prestupny rok.\n" ); else printf ( "neni prestupny rok.\n" ); Poznámka: vnější závorky okolo výrazu v návratové hodnotě funkce leapyear jsou zbytečné, ale někdy zpřehledňují kód funkce. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 18/48

Funkce příklady #include <stdio.h> /* --- Největší společný dělitel 1 --- */ int gcd ( int x, int y ) { int min = x < y x : y; while ( x % min y % min ) min --; return min; int main ( void ) { int a, b; printf ( "Napis dve prirozena cisla:\n" ); if ( scanf ( "%d %d", &a, &b )!= 2 a <= 0 b <= 0 ) { printf ( "Spatny vstup.\n" ); return 1; printf ( "gcd(%d,%d) = %d\n", a, b, gcd (a, b) ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 19/48

Funkce příklady #include <stdio.h> /* --- Největší společný dělitel 2 --- */ int gcd ( int x, int y ) { while ( x!= y ) if ( x > y ) x -= y; else y -= x; return x; int main ( void ) { int a, b; printf ( "Napis dve prirozena cisla:\n" ); if ( scanf ( "%d %d", &a, &b )!= 2 a <= 0 b <= 0 ) { printf ( "Spatny vstup.\n" ); return 1; printf ( "gcd(%d,%d) = %d\n", a, b, gcd (a, b) ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 20/48

Funkce příklady #include <stdio.h> /* --- Největší společný dělitel - Euklidův algoritmus --- */ int gcd ( int x, int y ) { int remainder = x % y; while ( remainder ) { x = y; y = remainder; remainder = x % y; return y; int main ( void ) { int a, b; printf ( "Napis dve prirozena cisla:\n" ); if ( scanf ( "%d %d", &a, &b )!= 2 a <= 0 b <= 0 ) { printf ( "Spatny vstup.\n" ); return 1; printf ( "gcd(%d,%d) = %d\n", a, b, gcd (a, b) ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 21/48

Procedury Procedura je podprogram řešící dílčí problém. Procedura nemá návratovou hodnotu. Procedury a funkce se liší právě jen návratovou hodnotou: v jazyce C jsou procedury funkcemi s návratovou hodnotou typu void, návrat z procedury do volající funkce nastane po provedení posledního příkazu procedury, nebo provedením příkazu return ;, na rozdíl od funkce, v příkazu return ; chybí argument výraz. Příklad vypsat větší ze dvou čísel: void printmax ( int x, int y ) { if ( x > y ) printf ( "%d", x ); else printf ( "%d", y ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 22/48

Vstupní a výstupní parametry Parametry jsou obvykle použity na předání vstupních dat podprogramu (algoritmu) implementovanému funkcí. Hodnoty parametrů jsou zkopírovány z volající funkce do formálních parametrů volané funkce, což jsou vlastně lokální proměnné volané funkce. Ty je možno ve funkci měnit. V jazyce C jsou parametry zásadně vstupní. Změny hodnot vstupních parametrů se tedy neprojeví ve volající funkci hodnoty parametrů nejsou kopírovány zpět při návratu. Tento způsob je obvykle výhodou zabraní nevyžádaným modifikacím hodnoty proměnné tvořící skutečný parametr volanou funkcí. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 23/48

Vstupní a výstupní parametry void printsequence ( int n, int start ) { int i; for ( i = 0; i < n; i ++ ) printf ( "%d\n", start ++ ); /* start je změněn */ int main ( void ) { int a = 3, b = 2; printsequence ( 5, 1 ); /* 1 2 3 4 5 */ printsequence ( a, b ); /* 2 3 4 */ /* a ani b nejsou změněny */ printsequence ( a, a + b ); /* 5 6 7 */ M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 24/48

Vstupní a výstupní parametry obsah paměti void printseq (int n, int st) { int i; for (i = 0; i < n; i ++) printf ( %d, st ++); main a 3 b 2 int main ( void ) { int a = 3, b = 2; printseq ( a, b ); printseq ( a, a+b ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 25/48

Vstupní a výstupní parametry obsah paměti void printseq (int n, int st) { int i; for (i = 0; i < n; i ++) printf ( %d, st ++); int main ( void ) { int a = 3, b = 2; printseq ( a, b ); printseq ( a, a+b ); main a 3 b 2 printseq n 3 st 2 i M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 25/48

Vstupní a výstupní parametry obsah paměti void printseq (int n, int st) { int i; for (i = 0; i < n; i ++) printf ( %d, st ++); int main ( void ) { int a = 3, b = 2; printseq ( a, b ); printseq ( a, a+b ); main a 3 b 2 printseq n 3 st 5 i 3 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 25/48

Vstupní a výstupní parametry obsah paměti void printseq (int n, int st) { int i; for (i = 0; i < n; i ++) printf ( %d, st ++); int main ( void ) { int a = 3, b = 2; printseq ( a, b ); printseq ( a, a+b ); main a 3 b 2 printseq n 3 st 5 i 3 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 25/48

Vstupní a výstupní parametry obsah paměti void printseq (int n, int st) { int i; for (i = 0; i < n; i ++) printf ( %d, st ++); main a 3 b 2 int main ( void ) { int a = 3, b = 2; printseq ( a, b ); printseq ( a, a+b ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 25/48

Vstupní a výstupní parametry obsah paměti void printseq (int n, int st) { int i; for (i = 0; i < n; i ++) printf ( %d, st ++); int main ( void ) { int a = 3, b = 2; printseq ( a, b ); printseq ( a, a+b ); main a 3 b 2 printseq n 3 st 5 i M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 25/48

Vstupní a výstupní parametry obsah paměti void printseq (int n, int st) { int i; for (i = 0; i < n; i ++) printf ( %d, st ++); int main ( void ) { int a = 3, b = 2; printseq ( a, b ); printseq ( a, a+b ); main a 3 b 2 printseq n 3 st 8 i 3 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 25/48

Vstupní a výstupní parametry obsah paměti void printseq (int n, int st) { int i; for (i = 0; i < n; i ++) printf ( %d, st ++); int main ( void ) { int a = 3, b = 2; printseq ( a, b ); printseq ( a, a+b ); main a 3 b 2 printseq n 3 st 8 i 3 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 25/48

Vstupní a výstupní parametry obsah paměti void printseq (int n, int st) { int i; for (i = 0; i < n; i ++) printf ( %d, st ++); main a 3 b 2 int main ( void ) { int a = 3, b = 2; printseq ( a, b ); printseq ( a, a+b ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 25/48

Vstupní a výstupní parametry Když má funkce vrátit dvě (nebo více) hodnot, jsou třeba výstupní parametry (jedna hodnota může být vrácena použitím mechanizmu return). Vstupní parametry nemohou předat hodnotu z volané do volající funkce. Programovací jazyky obvykle používají speciální modifikátory měnící chování parametrů (reference in C++, kĺıčové slovo var v Pascalu,... ). Taková možnost v jazyku C není. Místo toho je nutné pro výstupní parametr předat volané funkci ukazatel na proměnnou volající funkce: volající předá volané funkci ukazatel na proměnnou (adresu v paměti), který může fungovat jako výstupní parametr, ukazatel (adresa v paměti) je předán jako vstupní parametr, volaná funkce použije tuto adresu na přístup k proměnné volající funkce, kde může číst či zapsat hodnotu, ukazatel (adresa v paměti) zmizí při návratu. Ale hodnota proměnné ve volající funkci zůstane. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 26/48

Vstupní a výstupní parametry Když má mít funkce výstupní parametr typu T, deklaruje (vstupní) parametr typu T*, tj. ukazatel na typ T. Pro přístup k proměnné (výstupnímu parametru) je třeba ukazatel dereferencovat pomocí * (prefixový operátor hvězdička). Volající předává ukazatel (adresu) výstupní proměnné místo její hodnoty. Adresa proměnné je získána pomocí & (prefixový operátor ampersand). Hvězdičky v deklaraci se množí: požadovaný typ výstupního parametru deklarace formálního parametru int int * char char * double double * M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 27/48

Vstupní a výstupní parametry Když má mít funkce výstupní parametr typu T, deklaruje (vstupní) parametr typu T*, tj. ukazatel na typ T. Pro přístup k proměnné (výstupnímu parametru) je třeba ukazatel dereferencovat pomocí * (prefixový operátor hvězdička). Volající předává ukazatel (adresu) výstupní proměnné místo její hodnoty. Adresa proměnné je získána pomocí & (prefixový operátor ampersand). Hvězdičky v deklaraci se množí: požadovaný typ výstupního parametru deklarace formálního parametru int int * char char * double double * int * int ** int ** int *** M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 27/48

Vstupní a výstupní parametry Když má mít funkce výstupní parametr typu T, deklaruje (vstupní) parametr typu T*, tj. ukazatel na typ T. Pro přístup k proměnné (výstupnímu parametru) je třeba ukazatel dereferencovat pomocí * (prefixový operátor hvězdička). Volající předává ukazatel (adresu) výstupní proměnné místo její hodnoty. Adresa proměnné je získána pomocí & (prefixový operátor ampersand). Hvězdičky v deklaraci se množí: požadovaný typ výstupního parametru deklarace formálního parametru int int * char char * double double * int * int ** int ** int *** int (*)[5] int (**)[5] int (*)(void) int (**)(void) int (*(*)(int **))[7] int (*(**)(int **))[7] M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 27/48

Vstupní a výstupní parametry #include <stdio.h> void minmax ( int a, int b, int * min, int * max ) { if ( a < b ) { *min = a; *max = b; /* dereference min a max */ else { *max = a; *min = b; int main(void) { int a, b, max, min; printf ( "Napis dve cisla:\n" ); scanf ( "%d%d", &a, &b ); minmax ( a, b, &min, &max ); /* adresa min a max */ printf ( "min = %d, max = %d\n", min, max ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 28/48

Vstupní a výstupní parametry obsah paměti Nesprávné řešení void minmax ( int a, int b, int min, int max) { if ( a < b ) { min = a; max = b; else { min = b; max = a; main min max int main ( void ) { int min, max; minmax ( 3, 8, min, max ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 29/48

Vstupní a výstupní parametry obsah paměti Nesprávné řešení void minmax ( int a, int b, int min, int max) { if ( a < b ) { min = a; max = b; else { min = b; max = a; int main ( void ) { int min, max; minmax ( 3, 8, min, max ); main min max minmax a 3 b 8 min max M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 29/48

Vstupní a výstupní parametry obsah paměti Nesprávné řešení void minmax ( int a, int b, int min, int max) { if ( a < b ) { min = a; max = b; else { min = b; max = a; int main ( void ) { int min, max; minmax ( 3, 8, min, max ); main min max minmax a 3 b 8 min 3 max 8 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 29/48

Vstupní a výstupní parametry obsah paměti Nesprávné řešení void minmax ( int a, int b, int min, int max) { if ( a < b ) { min = a; max = b; else { min = b; max = a; int main ( void ) { int min, max; minmax ( 3, 8, min, max ); main min max minmax a 3 b 8 min 3 max 8 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 29/48

Vstupní a výstupní parametry obsah paměti Nesprávné řešení void minmax ( int a, int b, int min, int max) { if ( a < b ) { min = a; max = b; else { min = b; max = a; main min max int main ( void ) { int min, max; minmax ( 3, 8, min, max ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 29/48

Vstupní a výstupní parametry obsah paměti Správné řešení void minmax ( int a, int b, int * min, int * max) { if ( a < b ) { *min = a; *max = b; else { *min = b; *max = a; main min max int main ( void ) { int min, max; minmax ( 3, 8, &min, &max ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 30/48

Vstupní a výstupní parametry obsah paměti Správné řešení void minmax ( int a, int b, int * min, int * max) { if ( a < b ) { *min = a; *max = b; else { *min = b; *max = a; int main ( void ) { int min, max; minmax ( 3, 8, &min, &max ); main min max minmax a 3 b 8 min max M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 30/48

Vstupní a výstupní parametry obsah paměti Správné řešení void minmax ( int a, int b, int * min, int * max) { if ( a < b ) { *min = a; *max = b; else { *min = b; *max = a; int main ( void ) { int min, max; minmax ( 3, 8, &min, &max ); main min 3 max 8 minmax a 3 b 8 min max M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 30/48

Vstupní a výstupní parametry obsah paměti Správné řešení void minmax ( int a, int b, int * min, int * max) { if ( a < b ) { *min = a; *max = b; else { *min = b; *max = a; int main ( void ) { int min, max; minmax ( 3, 8, &min, &max ); main min 3 max 8 minmax a 3 b 8 min max M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 30/48

Vstupní a výstupní parametry obsah paměti Správné řešení void minmax ( int a, int b, int * min, int * max) { if ( a < b ) { *min = a; *max = b; else { *min = b; *max = a; main min 3 max 8 int main ( void ) { int min, max; minmax ( 3, 8, &min, &max ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 30/48

Vstupní a výstupní parametry Pro vstupní parametry se může lišit typ skutečného a formálního parametru. Například skutečný parametr typu int je zkonvertován na formální parametr typu double (v jazyce C dokonce i naopak). To neplatí pro výstupní parametry. Datové typy ukazatelů se musí přesně shodovat. Neshoda datových typů ukazatelů vede pouze na varovné hlášení. Nicméně je nepravděpodobné, že by takový program správně fungoval. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 31/48

Vstupní a výstupní parametry #include <stdio.h> void minmax ( int a, int b, int * min, int * max ) {... int main(void) { int ia, ib, imax, imin; float fa, fb, fmax, fmin;... M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 32/48

Vstupní a výstupní parametry #include <stdio.h> void minmax ( int a, int b, int * min, int * max ) {... int main(void) { int ia, ib, imax, imin; float fa, fb, fmax, fmin;... minmax(fa, ib+10, &imin, &imax ); /* ok - fa parametr se zkonvertuje na int */ M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 32/48

Vstupní a výstupní parametry #include <stdio.h> void minmax ( int a, int b, int * min, int * max ) {... int main(void) { int ia, ib, imax, imin; float fa, fb, fmax, fmin;... minmax(fa, ib+10, &imin, &imax ); /* ok - fa parametr se zkonvertuje na int */ minmax(fa, fb, &fmin, &fmax); /*!! varování - float *!= int * */ M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 32/48

Vstupní a výstupní parametry #include <stdio.h> void minmax ( int a, int b, int * min, int * max ) {... int main(void) { int ia, ib, imax, imin; float fa, fb, fmax, fmin;... minmax(fa, ib+10, &imin, &imax ); /* ok - fa parametr se zkonvertuje na int */ minmax(fa, fb, &fmin, &fmax); /*!! varování - float *!= int * */ minmax(ia, ib, &(imin + imax), &imax ); /*!!! chyba - nejde o l-value (proměnnou) */ M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 32/48

Vstupní a výstupní parametry #include <stdio.h> void minmax ( int a, int b, int * min, int * max ) {... int main(void) { int ia, ib, imax, imin; float fa, fb, fmax, fmin;... minmax(fa, ib+10, &imin, &imax ); /* ok - fa parametr se zkonvertuje na int */ minmax(fa, fb, &fmin, &fmax); /*!! varování - float *!= int * */ minmax(ia, ib, &(imin + imax), &imax ); /*!!! chyba - nejde o l-value (proměnnou) */ minmax(ia, ib, &imin + 10, &imax ); /*!! syntaxe ok - bude provádět něco zcela jiného */ M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 32/48

Vstupní a výstupní parametry #include <stdio.h> void minmax ( int a, int b, int * min, int * max ) {... int main(void) { int ia, ib, imax, imin; float fa, fb, fmax, fmin;... minmax(fa, ib+10, &imin, &imax ); /* ok - fa parametr se zkonvertuje na int */ minmax(fa, fb, &fmin, &fmax); /*!! varování - float *!= int * */ minmax(ia, ib, &(imin + imax), &imax ); /*!!! chyba - nejde o l-value (proměnnou) */ minmax(ia, ib, &imin + 10, &imax ); /*!! syntaxe ok - bude provádět něco zcela jiného */ minmax(ia, ib, &4, &imax ); /*!!! chyba - nejde o l-value */... M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 32/48

Alokace paměti Alokace paměti je dána kompilátorem a běhovým prostředím. Jak se rezervuje pamět pro proměnné: Globální proměnné jsou alokovány v datovém segmentu kompilátorem. Alokace je provedena jedinkrát v době kompilace (statická alokace) a je stejná po celou dobu běhu programu. Alokace lokálních proměnných funkce probíhá až za běhu programu. Prostor pro proměnné je vytvořen v momentu, kdy je třeba. Proměnné jsou alokovány až při volání funkce (nebo vstupu do bloku). Po návratu je pamět ový prostor uvolněn a může být použit jinou (nebo i stejnou) funkcí (blokem). To šetří pamět ovým prostorem a umožňuje např. rekurzi. Lokální proměnné jsou alokovány na zásobníku (stack). Zásobník pracuje v režimu LIFO (last-in, first-out) - poslední dovnitř, první ven. Když je funkce zavolána, její proměnné jsou alokovány na vrcholu zásobníku. Když funkce skončí (návratem do volající), vrchol zásobníku se vrátí do stavu před zavoláním funkce. Prostor, který zabíralo volání funkce se tím uvolní pro nové využití. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 33/48

Alokace paměti int g; void h ( int x ) {... void f ( void ) { int c, d; if (... ) { int e = 6; h(8+e); while (... ) { int f;... h(5); int main ( void ) { int a, b; f(); globals g 0 stack M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 34/48

Alokace paměti int g; void h ( int x ) {... void f ( void ) { int c, d; if (... ) { int e = 6; h(8+e); while (... ) { int f;... h(5); int main ( void ) { int a, b; f(); globals g 0 stack a b M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 34/48

Alokace paměti int g; void h ( int x ) {... void f ( void ) { int c, d; if (... ) { int e = 6; h(8+e); while (... ) { int f;... h(5); int main ( void ) { int a, b; f(); globals g 0 stack a b c d M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 34/48

Alokace paměti int g; void h ( int x ) {... void f ( void ) { int c, d; if (... ) { int e = 6; h(8+e); while (... ) { int f;... h(5); int main ( void ) { int a, b; f(); globals g 0 stack a b c d e 6 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 34/48

Alokace paměti int g; void h ( int x ) {... void f ( void ) { int c, d; if (... ) { int e = 6; h(8+e); while (... ) { int f;... h(5); int main ( void ) { int a, b; f(); globals g 0 stack a b c d e 6 x 14 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 34/48

Alokace paměti int g; void h ( int x ) {... void f ( void ) { int c, d; if (... ) { int e = 6; h(8+e); while (... ) { int f;... h(5); int main ( void ) { int a, b; f(); globals g 0 stack a b c d e 6 x 14 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 34/48

Alokace paměti int g; void h ( int x ) {... void f ( void ) { int c, d; if (... ) { int e = 6; h(8+e); while (... ) { int f;... h(5); int main ( void ) { int a, b; f(); globals g 0 stack a b c d e 6 x 14 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 34/48

Alokace paměti int g; void h ( int x ) {... void f ( void ) { int c, d; if (... ) { int e = 6; h(8+e); while (... ) { int f;... h(5); int main ( void ) { int a, b; f(); globals g 0 stack a b c d f 6 x 14 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 34/48

Alokace paměti int g; void h ( int x ) {... void f ( void ) { int c, d; if (... ) { int e = 6; h(8+e); while (... ) { int f;... h(5); int main ( void ) { int a, b; f(); globals g 0 stack a b c d f 6 x 14 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 34/48

Alokace paměti int g; void h ( int x ) {... void f ( void ) { int c, d; if (... ) { int e = 6; h(8+e); while (... ) { int f;... h(5); int main ( void ) { int a, b; f(); globals g 0 stack a b c d x 5 x 14 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 34/48

Alokace paměti int g; void h ( int x ) {... void f ( void ) { int c, d; if (... ) { int e = 6; h(8+e); while (... ) { int f;... h(5); int main ( void ) { int a, b; f(); globals g 0 stack a b c d x 5 x 14 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 34/48

Alokace paměti int g; void h ( int x ) {... void f ( void ) { int c, d; if (... ) { int e = 6; h(8+e); while (... ) { int f;... h(5); int main ( void ) { int a, b; f(); globals g 0 stack a b c d x 5 x 14 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 34/48

Složitost prvočísla Spočítat počet prvočísel menších než zadaná mez n. Odhadnout čas potřebný pro výpočet. Prvočíslo je přirozené číslo x větší než 1, které má jen dva dělitele 1 a x. Nástin algoritmu: pro všechna přirozená čísla x od 2 do n-1 když x je prvočíslo inkrementovat čítač změřit potřebný čas M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 35/48

Složitost prvočísla int countprimes ( int max ) { int i, cnt = 0; for ( i = 2; i < max; i ++ ) if ( isprime ( i ) ) /* budeme mít různé varianty */ cnt ++; return cnt; int main ( void ) { double timest; int cnt, max = 100000; timest = timestamp (); cnt = countprimes ( max ); printf ("%d prvocisel < %d, trvalo %.3f s\n", cnt, max, timestamp () - timest ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 36/48

Složitost prvočísla #include <time.h> #include <sys/time.h> double timestamp ( void ) { struct timeval tv; gettimeofday ( &tv, NULL ); /* funkce UNIX OS - čtení HW timeru */ /* Windows má obdobnou funkci - GetTickCount() */ return ( tv. tv_sec + 0.000001 * tv. tv_usec ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 37/48

Složitost prvočísla int isprime1 ( int n ) { int i, divisors = 0; if (n < 2) for (i = 1; i <= n; i++) if (n % i == 0) divisors ++; return ( divisors == 2 ); Číslo n je prvočíslem, když počet jeho dělitelů je právě 2. Kolik je iterací pro n = 1000000 Kolik je iterací pro n = 1000001 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 38/48

Složitost prvočísla int isprime2 ( int n ) { int i; if (n < 2) for (i = 2; i < n; i++) if (n % i == 0) return 1; Když je nalezen dělitel (různý od 1 a n), pak n není prvočíslo. Kolik je iterací pro n = 1000000 Kolik je iterací pro n = 1000001 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 39/48

Složitost prvočísla int isprime3 ( int n ) { int i; if (n < 2) for (i = 2; i <= n/2; i++) if (n % i == 0) return 1; Číslo n není prvočíslo, když existuje dělitel čísla n menší nebo roven n/2. Kolik je iterací pro n = 1000000 Kolik je iterací pro n = 1000001 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 40/48

Složitost prvočísla int isprime4 ( int n ) { int i; if (n < 2) for (i = 2; i <= sqrt ( n ); i++) if (n % i == 0) return 1; Číslo n není prvočíslo, když existuje dělitel čísla n menší nebo roven odmocnině z n. Kolik je iterací pro n = 1000000 Kolik je iterací pro n = 1000001 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 41/48

Složitost prvočísla int isprime5 ( int n ) { int i, max; if (n < 2) max = (int) sqrt ( n ); for (i = 2; i <= max; i++) if (n % i == 0) return 1; Výraz sqrt ( n ) byl vyhodnocován při každém průchodu cyklem. Odmocninu stačí vypočítat jen jednou, před cyklem. Kolik je iterací pro n = 1000000 Kolik je iterací pro n = 1000001 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 42/48

Složitost prvočísla int isprime6 ( int n ) { int i, max; if (n < 2) if (n == 2) return 1; if (n % 2 == 0) max = (int) sqrt ( n ); for (i = 3; i <= max; i += 2) if (n % i == 0) return 1; Není důvod testovat sudé dělitele. Když n není dělitelné 2, můžeme vynechat všechna sudá i. Kolik je iterací pro n = 1000000 Kolik je iterací pro n = 1000001 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 43/48

Složitost prvočísla 16 256 4096 65536 1 Mi 16 Mi 256 Mi 1 Gi isprime1 0.00 ms 0.19 ms 46.16 ms 10.85 s isprime2 0.00 ms 0.04 ms 5.95 ms 1.02 s isprime3 0.00 ms 0.02 ms 3.44 ms 547.20 ms isprime4 0.00 ms 0.03 ms 1.27 ms 51.87 ms 2.49 s isprime5 0.01 ms 0.02 ms 0.46 ms 15.46 ms 755.09 ms 32.96 s isprime6 0.00 ms 0.01 ms 0.25 ms 8.15 ms 385.29 ms 16.62 s M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 44/48

Složitost prvočísla 16 256 4096 65536 1 Mi 16 Mi 256 Mi 1 Gi isprime1 0.00 ms 0.19 ms 46.16 ms 10.85 s isprime2 0.00 ms 0.04 ms 5.95 ms 1.02 s isprime3 0.00 ms 0.02 ms 3.44 ms 547.20 ms isprime4 0.00 ms 0.03 ms 1.27 ms 51.87 ms 2.49 s isprime5 0.01 ms 0.02 ms 0.46 ms 15.46 ms 755.09 ms 32.96 s isprime6 0.00 ms 0.01 ms 0.25 ms 8.15 ms 385.29 ms 16.62 s sieve 0.06 ms 0.00 ms 0.06 ms 0.98 ms 16.52 ms 283.51 ms 9.14 s 40.64 s M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 44/48

Složitost prvočísla Celkový čas závisí na n. Naměřené hodnoty naznačují exponenciální nárůst. Program sieve je založen na algoritmu Eratosthenova síta na prvočísla. Ten je nejrychlejší, avšak stále exponenciální. Proč exponenciální Není lineární M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 45/48

Složitost prvočísla Celkový čas závisí na n. Naměřené hodnoty naznačují exponenciální nárůst. Program sieve je založen na algoritmu Eratosthenova síta na prvočísla. Ten je nejrychlejší, avšak stále exponenciální. Proč exponenciální Není lineární Důležitý je základ. Typicky se počet operací vyjadřuje ve vztahu k velikosti vstupu (počtu bitů na vstupu). Náš program počítal počet prvočísel menších než n. Pro zadání čísla n bylo potřeba b = log 2 (n) bitů vstupu. Tedy n = 2 b. Programy provedly testy čísel 1 až n, každé testování zabralo nejvýše n pokusů o dělení, lepší varianty méně. Celkově tedy bylo provedeno až n 2 operací (horní odhad). Tato hodnota vyjádřena pomocí velikosti vstupu b dává: n 2 = (2 b ) 2 = 2 2b, tedy program opravdu má exponenciální složitost. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 45/48

Složitost prvočísla Předpokládejme ideální algoritmus, který pomocí jediné operace rozhodne, zda x je pročíslo: takový algoritmus je hypotetický, nejlepší známé testy prvočíselnosti pracují v polynomiálním čase log K 2 (x) = a K, K je konstanta, a je počet bitů testovaného čísla x. Jedná se o pravděpodobnostní testy prvočíselnosti (Rabin-Miller, Agrawal-Biswas) a deterministický test prvočíselnosti (Agrawal-Kayal-Saxena). Pokud bychom tímto ideálním algoritmem otestovali čísla od 1 do n, musíme jej použít n-krát. Celková složitost bude n = 2 b, tedy opět exponenciální (dolní odhad). M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 46/48

Složitost hledání maxima Uvažme jiný problém: nalezení maxima v n vstupních číslech. Vstupem je n čísel, tedy velikost vstupu je b = n K bitů (předpokládáme K bitů na jedno číslo). Program musí porovnat těchto n čísel, tedy potřebuje provést 3n operací (čtení, porovnání a případné uložení nového maxima). Celková složitost bude 3n = 3 K b, tedy jedná se o lineární složitost vzhledem k velikosti vstupu. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 47/48

Otázky a odpovědi Otázky... M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Funkce, BI-PA1 48/48