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
A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce
Zobrazení jména a hodnoty dat na obrazovce
4
Funkce - vstupní a výstupní data • •
Funkce může mít více vstupních dat 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
Funkce
Procedura – „něco“ vykoná
Funkce
A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce
Procedura
Procedura
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
A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce
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
A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce
Procedura
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
A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce
Procedura
Procedura
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 Funkce
Předává se přečtené n
Čtení přirozeného čísla
faktorial Funkce
Předává se vypočtený faktoriál
Algoritmus výpočtu faktoriálu
tiskVysledku Procedura
A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce
Tisk výsledku
10
Faktoriál pomocí funkcí (1) •
Funkce pro čtení přirozeného čísla 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
Faktoriál pomocí funkcí (3) •
Procedura pro tisk výsledku výpočtu 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 #include <stdio.h> #include <stdlib.h>
#include <stdio.h> #include <stdlib.h>
extern funkceB(void); extern funkceC(void); int x1, x2=0, y=54;
extern funkceA(void); Začátek programu char funkceB (void) { double d; d = funkceD ( ); ……… } Fce v jiném modulu
void main (String[] args) { int x = funkceA ( 35 ); funkceC ( x, c1 ); } int funkceA (int x) { char s; s = funkceB ( ); ........ }
void funkceC (int r1, char c) { printf (……..); ......... } Konec programu
A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce
16
Struktura funkce/procedury Jméno funkce
Typ návratové hodnoty
Formální parametr(y) funkce double funkceA ( int x ) {
const double MIN = 1000.0; double v = 1.0; int n;
Hlavička funkce Začátek funkce Lokální konstanty Lokální proměnné
for( n=0; n<10; n++) { v = v * 4.5 + 305.9; } if( v > MIN ) v = v - 255.6; return v ; }
A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce
Kód funkce Návratová hodnota Zdrojový modul (soubor)
Konec 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); // nesmyslný příkaz scanf("%d",&y); // nesmyslný příkaz if (x > y) return x; else Nesmysl return y; 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; pocet = plat/hodnBankovky; plat=plat%1000; plat = plat%hodnBankovky; p500=plat/500; plat=plat%500; p100=plat/100; plat=plat%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); } 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 může metodu return false; } 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) int nsd(int x, int 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 d; if (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
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(); Globální proměnná printf(”%d”,a); } void f() { int a = 20; printf(”%d”,a); } Program vypíše 20 10
A8B14ADP Algoritmizace a programovaní -Jazyk C - funkce
Lokální proměnná, zastíní globální proměnnou stejného jména
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 ... a Proměnné } v paměti arg 1
c x b
b
b
a
a
a
a
arg
arg
arg
arg
2
3
4
5
krok 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