Algoritmizace a programování Jazyk C funkce České vysoké učení technické Fakulta elektrotechnická A8B14ADP Algoritmizace a programovaní -Jazyk C -Ver.1.00 funkce J. Zděnek 20151
Funkce Funkce - černá (programová) skřínka pro určitý výpočetní úkon Známe - co počítá Nezajímá nás jak to počítá Má určené místo pro vstup informace se kterou metoda počítá vstup dat Má určené místo pro výstup zpracované informace výstup dat Princip umožňuje řešit složité úkoly rozkladem na jednodušší navzájem spolupracující části (metody) Vstup dat Metoda má jméno Známe co metoda počítá Funkce Nezajímá nás jak to počítá Výstup dat A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 2
Funkce bez vstupů Funkce nemusí mít vstup dat Má pouze výstup dat Např: Čtení hodnoty z klávesnice Výstupem funkce přečtená hodnota Čtení hodnoty z klávesnice Funkce Výstup dat = přečtená hodnota A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 3
Funkce bez výstupů Funkce nemusí mít výstup dat, pouze vykoná nějakou činnost Má pouze vstup dat Např: zobrazení hodnoty na obrazovce Vstupem funkce jméno a hodnota zobrazovaných dat Vstup dat = Jméno a hodnota toho co se má zobrazit Funkce Zobrazení jména a hodnoty dat na obrazovce A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 4
Funkce může mít více vstupních dat Funkce - vstupní a výstupní data Funkce může mít i více výstupních dat Funkce typu funkce má pouze jednu hodnotu výstupní Procedura je funkce, která má definovány vstupní hodnoty a svou činnost nemívá žádná výstupní data Funkce vždy pouze jednu výstupní hodnotu Procedura něco vykoná Funkce Funkce Procedura Procedura A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 5
Funkce Funkce typu funkce má pouze jednu hodnotu hodnotu funkce Funkci lze použít ve výrazu Např: y = 2*x + sin(x), y = 2*x + sin(x); sin(x) je funkce Funkce vždy pouze jednu výstupní hodnotu Sin(x) Funkce Funkce A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 6
Procedura Procedura je funkce, která má definovány vstupní hodnoty a svou činnost - nemívá žádná výstupní data Procedura ale může změnit Hodnotu nelokální proměnné nedoporučeno proč? Hodnoty proměnných, je-li vstupní hodnotou reference na proměnnou Proceduru nelze použít ve výrazu Procedura něco vykoná Procedura Procedura A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 7
Funkce a procedura vstupní data Pravidla pro zápis vstupních dat jsou pro funkci i pro proceduru stejná Pravidla pro zápis vstupních dat pro funkci i proceduru stejná Funkce Funkce Procedura Procedura A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 8
Funkce, rozklad na dílčí problémy Připomeňme si program pro výpočet faktoriálu: void main(int argc, char** argv) { int n, i, j; printf("zadejte přirozené číslo \n "); scanf("%d",&n); if (n < 1) { printf(n + " není přirozené číslo"); return; i = 1; f = 1; while (i < n) { i = i + 1; f = f * i; printf("n = %d, f! = %d", n, f); return; Čtení přirozeného čísla Algoritmus výpočtu faktoriálu Tisk výsledku Čtení přirozeného čísla, výpočet faktoriálu a tisk výsledku jsou tři dílčí podproblémy, jejichž řešení popíšeme samostatnými funkcemi A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 9
Řešení problému rozkladem na dílčí problémy ctiprirozene Předává se přečtené n Předává se vypočtený faktoriál faktorial tiskvysledku Funkce Funkce Procedura Čtení přirozeného čísla Algoritmus výpočtu faktoriálu Tisk výsledku A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 10
Funkce pro čtení přirozeného čísla Faktoriál pomocí funkcí (1) int ctiprirozene(void) { int n; printf("zadejte přirozené číslo"); scanf("%d",&n); if (n < 1) { printf("%d není přirozené číslo", n); exit(0); return n; Hlavička funkce int ctiprirozene(void) vyjadřuje, že funkce nemá parametry (prázdná závorka) a že výsledkem volání funkce je hodnota typu int Příkaz return n; předepisuje návrat z funkce, výsledkem volání je hodnota n Příklad volání funkce: nn = ctiprirozene(); A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 11
Faktoriál pomocí funkcí (2) Funkce pro výpočet faktoriálu int faktorial(int n) { int i = 1; int f = 1; while (i < n) { i = i + 1; f = f * i; return f; Hlavička funkce vyjadřuje, že funkce má jeden vstupní parametr typu int a že výsledkem je hodnota typu int Příklad volání funkce ff = faktorial(4); A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 12
Procedura pro tisk výsledku výpočtu Faktoriál pomocí funkcí (3) void tiskvysledku(int n, int f) { printf("n = %d, f! = %d",n,f); Hlavička vyjadřuje, že procedura má dva vstupní parametry (int, int). Procedura nevrací žádnou hodnotu (void). Příklad volání procedury tiskvysledku(n, f); A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 13
Faktoriál pomocí funkcí (4) Výsledné řešení: #include <stdio.h> #include <stdlib.h> void main(int argc, char** argv) { int n, fakt; n = ctiprirozene(); fakt = faktorial(n); tiskvysledku(n,fakt); int ctiprirozene() { int faktorial(int n) { void tiskvysledku(int n,int f){ A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 14
Deklarace funkce Deklaraci funkce tvoří hlavička funkce tělo funkce Hlavička funkce v jazyku C má tvar typ jméno(specifikace parametrů) kde typ je typ výsledku funkce (funkční hodnoty) jméno je identifikátor funkce specifikací parametrů se deklarují parametry funkce, každá deklarace má tvar typ_parametru jméno_parametru (a oddělují se čárkou) specifikace parametrů je prázdná, jde-li o funkci bez parametrů Tělo funkce je složený příkaz nebo blok, který se provede při volání funkce Tělo funkce musí končit příkazem return x; kde x je výraz, jehož hodnota je výsledkem volání funkce A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 15
Bloková struktura programu void main (String[] args) { int x = funkcea ( 35 ); funkcec ( x, c1 ); int funkcea (int x) { #include <stdio.h> #include <stdlib.h> extern funkceb(void); extern funkcec(void); int x1, x2=0, y=54; char s; s = funkceb ( );........ Začátek programu Konec programu char funkceb (void) { void funkcec (int r1, char c) { printf (..); #include <stdio.h> #include <stdlib.h> extern funkcea(void); double d; d = funkced ( );......... Fce v jiném modulu A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 16
Struktura funkce/procedury Typ návratové hodnoty double funkcea ( int x ) { Jméno funkce Formální parametr(y) funkce Hlavička funkce const double MIN = 1000.0; double v = 1.0; int n; for( n=0; n<10; n++) { v = v * 4.5 + 305.9; if( v > MIN ) v = v - 255.6; return v ; Začátek funkce Lokální konstanty Lokální proměnné Kód funkce Návratová hodnota Zdrojový modul (soubor) Konec funkce A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 17
Vstupní parametry funkce Parametry funkce jsou lokální proměnné funkce, kterým se při volání funkce přiřadí hodnoty skutečných parametrů Jestliže parametr funkce je typu T, pak přípustným skutečným parametrem je výraz, jehož hodnotu lze přiřadit proměnné typu T (stejná podmínka, jako u přiřazení) Příklad: int max(int x, int y) { if (x > y) return x; else return y; void main(int argc, char** argv) { int a = 10, b = 20; printf("max = %d",max(a+20, b)); A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 18
Vstupní parametry funkce Vstupní parametry funkce slouží pro předání vstupních dat algoritmu, který je funkcí realizován Častá chyba začátečníka: funkce, která čte hodnoty parametrů pomocí operace vstupu dat (např. čtení klávesnice) int max(int x, int y) { scanf("%d",&x); scanf("%d",&y); if (x > y) return x; else return y; // nesmyslný příkaz // nesmyslný příkaz Nesmysl Proč? int z; z = max(7,99); A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 19
Hodnota funkce Typ návratové hodnoty se uvádí před názvem funkce Návratová hodnota (proměnná, výraz) se uvádí za příkazem return Funkce může vracet pouze jednu návratovou hodnotu Návratovou hodnotou může být i ukazatel (pointer) int max(int x, int y) { int maxhodnota = y; if (x > y) maxhodnota = x; return maxhodnota; max Funkce Návratová hodnota A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 20
Formální a skutečné parametry funkce void main(int argc, char** argv){ int a = 4; int b = 2; int m = max(a,b); printf("max = %d",m); m = max(b,6); printf("max = %d",m); int max(int x, int y) { int maxhodnota = y; if (x > y) maxhodnota = x; return x; Skutečné parametry Skutečné parametry obsahují aktuální předávaná data do metody Formální parametry Formální parametry umožní v těle metody popsat, jak má algoritmus zpracovat vstupní data Formální parametry jsou lokální proměnné A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 21
Příklad Výplata hotovosti (1) Výplata hotovosti (výčetka platidel) se odevzdává bance, uvádí vždy hodnotu bankovky a počet bankovek My budeme hledat takovou výčetku, která pro danou částku obsahuje celkově nejmenší počet bankovek Příklad: (pro jednoduchost uvažujme pouze bankovky 5000, 1000, 500 a 100 Kč) Částka = 38 900 bankovka (Kč) počet (ks) 5000 7 1000 3 500 1 100 4 A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 22
Příklad - Výplata hotovosti (2) void main(int argc, char** argv){ int plat,platx,p5000,p1000,p500,p100; prinf( Zadej plat = ); scanf( %d,&plat); platx = plat; p5000=plat/5000; plat=plat%5000; p1000=plat/1000; plat=plat%1000; p500=plat/500; plat=plat%500; p100=plat/100; plat=plat%100; pocet = plat/hodnbankovky; plat = plat%hodnbankovky; printf("vyplata castky %d je \n,platx); printf( %d \n%d \n%d \n%d \n,p5000,p1000,p500,p100); printf( zbytek %d \n,plat); A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 23
Výplata hotovosti s funkcí (3) int plat; void main(int argc, char** argv){ int p5000,p1000,p500,p100,platx; prinf( Zadej plat = ); scanf( %d,&plat); platx = plat; p5000 = pocetbankovek(5000); p1000 = pocetbankovek(1000); p500 = pocetbankovek(500); p100 = pocetbankovek(100); printf("vyplata castky %d je \n,platx); printf( %d \n%d \n%d \n%d \n,p5000,p1000,p500,p100); printf( zbytek %d \n,plat); int pocetbankovek(int hodnotabankovky){ int pocet; pocet = plat/hodnotabankovky; plat = plat%hodnotabankovky; return pocet; ; A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 24
Příklady funkcí Funkce pro zjištění, zda daný rok je přestupný void main(int argc, char** argv){ int rok; printf( Zadejte rok \n"); scanf( %d,&rok); printf("rok = %d \n,rok); if (prestupnyrok(rok)) printf( Je prestupny \n"); else printf( Neni prestupny \n"); int prestupnyrok(int rok){ if (rok%4 == 0 && (rok%100!= 0 rok%1000 == 0)) return true; else return false; return může metodu ukončit na více místech A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 25
Funkce pro výpočet NSD (1) Efektivní algoritmus lze sestavit na základě těchto vztahů: je-li x = y, pak nsd(x,y) = x je-li x > y, pak nsd(x,y) = nsd(x-y,y) je-li x < y, pak nsd(x,y) = nsd(x,y-x) Řešení 1: int nsd(int x, int y) { while (x!= y) if (x > y) x = x - y; else y = y - x; return x; int nsd(int x, int y) { int d; if (x<y) d=x; else d=y; while (x%d!=0 y%d!=0) d--; return d; void main(int argc, char** argv) { int a, b; scanf( %d,&a);scanf( %d,&b); printf( Nejv.spol.del.%d a %d je %d\n,a,b,nsd(a,b)); A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 26
Funkce pro výpočet NSD (2) Do těla cyklu vnoříme místo podmíněného příkazu pro jediné zmenšení hodnoty x nebo y dva cykly pro opakované zmenšení hodnot x a y Řešení 2: int nsd(int x, int y) { while(x!= y) { while(x > y) x = x-y; while(y > x) y = y-x; return x; void main(int argc, char** argv) { int a, b; scanf( %d,&a);scanf( %d,&b); printf( Nejv.spol.del.%d a %d je %d\n,a,b,nsd(a,b)); A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 27
Euklidův algoritmus pro výpočet NSD (3) Vnitřní cykly řešení 2 počítají nenulový zbytek po dělení většího čísla menším Pro výpočet zbytku po dělení máme operaci % Jejím využitím dostaneme Euklidův algoritmus, který lze slovně formulovat takto: určíme zbytek po dělení daných čísel, zbytkem dělíme dělitele a určíme nový zbytek, až dosáhneme nulového zbytku; poslední nenulový zbytek je nsd. Řešení 3: int nsd(int x, int y) { int zbytek; zbytek = x % y; while (zbytek!= 0) { x = y; y = zbytek; zbytek = x % y; return y; void main(int argc, char** argv) { int a, b; scanf( %d,&a);scanf( %d,&b); printf( Nejv.spol.del.%d a %d je %d\n,a,b,nsd(a,b)); A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 28
Procedury Funkce, jejíž typ výsledku je void, nevrací žádnou hodnotu Funkce, která nevrací žádnou hodnotu, se nazývá procedura Předávání vstupních dat do procedury se řídí stejnými pravidly jako u funkce Procedura může vracet vypočítané hodnoty (!) - způsob bude probrán v dalších lekcích. Příklady procedury: Hlavní funkce main Tisk na obrazovku printf( ) Příklad uživatelské procedury: Výpis znaku zn doplněného zleva mezerami na celkový počet n znaků void vypisznak(char zn, int n) { int i; for (i = 1; i < n; i++) printf( ); printf( %c \n,zn); A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 29
Statické proměnné Program může obsahovat deklarace statických proměnných Statické třídy jsou použitelné ve všech funkcích jsou to pro ně globální proměnné Příklad: int x, y; //Deklarovane mimo telo funkci void main(int argc, char** argv){ printf( Zadejte dvě celá čísla \n"); scanf( %d,&x); scanf( %d,&y); // printf( %d \n,i); // Nelze, i zde neznama vypissoucet(); void vypissoucet(void) { int i = 6; printf( Součet čísel je %d, i = %d \n,(x+y),i); Poznámka: statické proměnné jsou inicializovány hodnotou nula A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 30
Hvězdičky procedury (1) void hvezdickyln(int pocet){ int i; for(i = 1; i <= pocet; i++)printf( * ); printf( \n ); void hvezdicky(int pocet){ int i; for(i = 1; i <= pocet; i++)printf( * ); void mezeryln(int pocet){ int i; for(i = 1; i <= pocet; i++)printf( ); printf( \n ); void mezery(int pocet){ int i; for(i = 1; i <= pocet; i++)printf( ); A0B36PRI A8B14ADP PROGRAMOVÁNÍ Algoritmizace a programovaní 04 -Jazyk C - funkce 31
Hvězdičky procedury (2) void main(int argc, char** argv){ hvezdickyln(5); mezery(4); hvezdicky(10); mezeryln(0); hvezdickyln(5); ***** ***** ********** A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 32
Zastínění nelokální proměnné Deklarace lokální proměnné x zastíní deklaraci globální proměnné Příklad: int a = 10; void main(int argc, char** argv){ f(); printf( %d,a); Globální proměnná void f() { int a = 20; printf( %d,a); Program vypíše 20 10 Lokální proměnná, zastíní globální proměnnou stejného jména A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 33
Přidělování paměti proměnným Poznali jsme doposud dva druhy proměnných: globální proměnné lokální proměnné funkcí Přidělením paměti proměnné rozumíme určení adresy umístění proměnné v paměti počítače Globálním proměnným třídy se přidělí paměť v okamžiku, kdy se do paměti zavádí kód fprogramu, a zůstane jim přidělena až do ukončení běhu programu. Lokálním proměnným a parametrům funkce se paměť přidělí při každém volání funkce a zůstane jim přidělena jen do návratu z funkce ( při návratu z funkce se přidělené adresy uvolní pro další použití). Úseky paměti přidělované lokálním proměnným a parametrům tvoří tzv. zásobník (stack, LIFO): úseky se přidávají a odebírají, přičemž se vždy odebere naposledy přidaný úsek zásobník A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 34
Přidělování paměti proměnným Příklad void main(int argc, char** argv){ int a; // 1 f();... // 5 void f() { int b; // 2 g(10);... // 4 void g(int x) { int c; // 3... Proměnné v paměti b c x b a a a a a arg arg arg arg arg b krok 1 2 3 4 5 A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 35
Algoritmizace a programování Jazyk C funkce Konec České vysoké učení technické Fakulta elektrotechnická A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce 36