Hotelová škola , Obchodní akademie a Střední průmyslová škola Teplice,Benešovo náměstí 1, příspěvková organizace
VZDĚLÁVACÍ MATERIÁL ZPRACOVÁN V RÁMCI PROJEKTU „EU PENÍZE STŘEDNÍM ŠKOLÁM“- OPVK 1.5 Registrační číslo projektu: Název projektu:
Šablona:
III/2
CZ.1.07/1.5.00/34.0528 ICT ve výuce
Č. materiálu:
VY_32_INOVACE_ICT_813
Jméno autora:
Ing. Jiří ILKIV
Datum vytvoření:
13.08.2012
Předmět:
Programování
Tematická oblast:
Funkce v jazyku C++
Obor vzdělání:
18-20-M/01 Informační technologie
Ročník:
2.
Popis způsobu použití výukového Digitální výukový materiál určený pro výuku předmětu PROGRAMOVÁNÍ. Digitální učební materiál materiálu ve výuce: seznamuje prezentací žáka/žákyni s pojmy funkce, parametr funkce, návratová hodnota jazyk, program, programování, C++, funkce, Klíčová slova:
parametr funkce, návratová hodnota
Druh učebního materiálu:
Inovativní vzdělávací materiál
Ověřeno ve třídě:
2V
Období ověřování:
12/2012
Ing. Jiří ILKIV VY_32_INOVACE_ICT_813
13. Funkce v jazyku C++ Funkce rozkládají velké výpočetní úlohy na menší. Stejná funkce je opakovaně využitelná v různých výpočetních úlohách a tím funkce umožňují lidem vycházet z práce ostatních, místo aby museli začínat úplně od začátku. Správné funkce skrývají detaily výpočtu (detaily implementace) před částmi programu, které je nemusí znát, čímž zpřehledňují celý program a usnadňují případné změny. Program je pak v podstatě sada 1
definic proměnných a funkcí . Komunikace mezi funkcemi a proměnnými probíhá prostřednictvím argumentů funkcí a návratových hodnot funkcí.
13.1. Deklarace funkce 2
Pokud se na funkci podíváme jako na "černou skříňku" , jejíž vnitřní uspořádání je nám skryto, vidíme jen to, co do funkce vstupuje (argumenty) a to, co z funkce vystupuje (návratová hodnota). Představme si funkci pojmenovanou "sečti dvě čísla", jejíž "prací" je sečíst nějaká dvě čísla a vrátit nám výsledek. Z pohledu "černé skříňky" by tato funkce mohla vypadat třeba takto:
(VSTUP) (VÝSTUP) tj. "vstupní argumenty funkce":
tj. "návratová hodnota funkce":
číslo X
číslo Y
funkce „sečti dvě čísla“
součet čísel X a Y
V jazyku C++ vyjádříme výše uvedený obrázek tzv. "deklarací" funkce. Všimněte si, že deklarace se vůbec nezabývá detaily implementace funkce, tj. jejím vnitřním uspořádáním. Deklarace se zpravidla vyjádří jedním řádkem textu, ukončeným středníkem:
int sectiDveCisla(int X, int Y) ;
ukončovací středník
seznam argumentů
název funkce
typ návratové hodnoty
1
V dalším se seznámíme ještě s tzv. 'objekty', ale zatím je pro naše potřeby tento popis od pánů Kerninghana a Ritchieho, tvůrců jazyka C (předchůdce C++), zcela vyhovující.
2
Pojem "černá skříňka" je pojem používaný v systémovém inženýrství., "Černá skříňka" skrývá vnitřní uspořádání nějakého podsystému, které nás na dané úrovni úvah a v daném okamžiku nezajímá. "Černá skříňka" tak má pro nás jen vstupy a výstupy.
1/9 Autorem materiálu a všech jeho částí, není‐li uvedeno jinak, je Ing. Jiří Ilkiv. Dostupné z Metodického portálu www.rvp.cz, ISSN: 1802‐4785, financovaného z ESF a státního rozpočtu ČR. Provozuje Národní ústav pro vzdělávání, školské poradenské zařízení a zařízení pro další vzdělávání pedagogických pracovníků.
Ing. Jiří ILKIV VY_32_INOVACE_ICT_813 Deklaraci funkce uvádíme v projektu v Microsoft Visual Studiu zpravidla v tzv. "hlavičkovém souboru" s koncovkou .h ve složce "Header Files" aktuálního projektu. Na obrázku vidíme otevřený projekt, který ve složce "Header Files" obsahuje soubor deklarací funkce.h:
obr.1: umístění souboru deklarací v Microsoft Visual C++ projektu
13.1.1 Název funkce V názvu funkce stojí za povšimnutí absence české diakritiky ( "secti..." místo "sečti..."). Na to si 3
v jazyku C++ musíme zvyknout, že názvy funkcí budeme psát bez háčků a čárek. Dále název funkce nesmí obsahovat mezery. První znak názvu funkce nesmí být číslice, závorky apod. Zůstaneme u toho, že název funkce bude vždy začínat písmenem. S mezerami v názvu funkce se můžeme vypořádat několika způsoby. Všeobecně jsou nejrozšířenější tyto dva způsoby:
int sectiDveCisla(int X, int Y); int secti_dve_cisla(int X, int Y);
3
Názvy proměnných, funkcí a dalších objektů, které používáme v programu, píšeme bez háčků, čárek a ostatních diakritických znamének. To však neznamená, že proměnná, např. jméno osoby, v sobě nemůže obsahovat text s háčky a čárkami. A funkce může texty s háčky a čárkami i vracet. Musíme zde totiž rozlišovat mezi "názvem" proměnné (nebo funkce) a "obsahem" proměnné (nebo návratovou hodnotou funkce).
2/9 Autorem materiálu a všech jeho částí, není‐li uvedeno jinak, je Ing. Jiří Ilkiv. Dostupné z Metodického portálu www.rvp.cz, ISSN: 1802‐4785, financovaného z ESF a státního rozpočtu ČR. Provozuje Národní ústav pro vzdělávání, školské poradenské zařízení a zařízení pro další vzdělávání pedagogických pracovníků.
Ing. Jiří ILKIV VY_32_INOVACE_ICT_813 Ten první se nazývá "velbloudí" způsob, všimněte si hrbů tvořených písmeny D a C. Je doporučován a dodržován např. programátory firmy Microsoft. Někomu se zdá přehlednější styl druhý. Zpravidla je způsob volby jmen funkcí i jiných objektů použitých v programu stanoven vnitřní filozofií každé jednotlivé softwarové firmy, pro kterou programátor pracuje. Jakmile si však jeden způsob zvolíte, musíte jej dodržovat v celém projektu. Střídání způsobů je znakem špatného programovacího stylu a zpravidla je i zdrojem chyb, způsobených nepřehledností kódu. Použitím stylu: int _secti_dve_cisla(int X, int Y); (!!!) si říkáme o malér, neboť mnoho programovacích jazyků (i C++) používá znak podtržítka "_" na začátku jména pro systémové funkce a mohli bychom se do názvu některé z nich "trefit". To by mělo pro běh programu fatální následky včetně konečného zhroucení aplikace. My budeme v dalším výkladu preferovat styl "velbloudí".
13.1.2 Návratová hodnota funkce Na začátku deklarace je uveden "typ návratové hodnoty funkce". Jazyk C++ je jazyk s typovou kontrolou a nedovolí zapisovat libovolné hodnoty na libovolná místa v paměti (například číslo nelze zapsat do místa paměti určeného pro text a naopak). Takže pokud v deklaraci napíšeme, že funkce vrací celočíselnou (int) hodnotu, pak tuto vrácenou hodnotu (výsledek "práce" funkce) musíme v programu uložit do proměnné stejného (int) typu: int main(){ ... int A = 10; int B = 20; int vysledek;
//proměnná je int
vysledek = sectiDveCisla(A, B);
//funkce vrací int
cout << vysledek << endl; ... }
Pokud bychom se snažili o uložení vrácené hodnoty funkce do proměnné jiného typu, bude při překladu programu 4
zpravidla generována chyba.
4
Chyba (Error) je překladačem Microsoft Visual Studia generována při naprostém nesouladu typů (např.: int a string). Pokud lze typ převést na jiný typ, např. (int na double) nebo pokud akceptujeme určitou ztrátu informací (např. ztrátu desetinné části čísla při převodu double na int), pak to překladač provede ale generuje tzv. "upozornění" (Warning). To by nás mělo přimět, abychom prozkoumali, je‐li neshoda typů opravdu naším záměrem, nebo jsme něco přehlédli.
3/9 Autorem materiálu a všech jeho částí, není‐li uvedeno jinak, je Ing. Jiří Ilkiv. Dostupné z Metodického portálu www.rvp.cz, ISSN: 1802‐4785, financovaného z ESF a státního rozpočtu ČR. Provozuje Národní ústav pro vzdělávání, školské poradenské zařízení a zařízení pro další vzdělávání pedagogických pracovníků.
Ing. Jiří ILKIV VY_32_INOVACE_ICT_813 Funkci můžeme použít také přímo na místě, kde by mohla být proměnná, a pak se funkce chová jako proměnná toho typu, který jsme jí stanovili jako typ návratový:
int main(){ ... ... int A = 10; int B = 20; cout << sectiDveCisla(A, B) << endl;
... ... }
Použijeme‐li funkci na místě proměnné, musí být návratový typ této funkce v souladu s požadovaným typem té proměnné, na jejímž místě stojí. V níže uvedeném příkladu (který sčítá za pomoci funkce soucetDvouCisel čísla tři) je funkce správně použita na místě argumentu typu int:
int main(){ ... ... int A1 = 4; int A2 = 6; int B = 20; cout << sectiDveCisla( sectiDveCisla(A1, A2), B) << endl;
... ... }
funkce je zde použita na místě proměnné
typu int a vrací vrací hodnotu 10
4/9 Autorem materiálu a všech jeho částí, není‐li uvedeno jinak, je Ing. Jiří Ilkiv. Dostupné z Metodického portálu www.rvp.cz, ISSN: 1802‐4785, financovaného z ESF a státního rozpočtu ČR. Provozuje Národní ústav pro vzdělávání, školské poradenské zařízení a zařízení pro další vzdělávání pedagogických pracovníků.
Ing. Jiří ILKIV VY_32_INOVACE_ICT_813
13.1.3 Seznam argumentů Seznam argumentů se uvádí v kulatých závorkách za názvem funkce. Pokud je argumentů více, jsou jednotlivé argumenty v seznamu navzájem odděleny čárkou. Počet argumentů funkce není omezen ale dobře navržené funkce mívají maximálně jeden až dva argumenty. Seznam argumentů je v podstatě seznam hodnot se 5
kterými může funkce pracovat. Argumenty mají své pořadí, svůj typ a své jméno, tímto jménem budou uvnitř funkce rozlišovány:
int X , int Y ) ;
int sectiDveCisla(
název 2. argumentu
typ 2. argumentu
čárka oddělující položky seznamu
název 1. argumentu
typ 1. argumentu
5
Funkce může pracovat ještě s tzv. globálními proměnnými. To jsou proměnné, ke kterým má přístup kterákoli funkce, aniž by je měla uvedeny ve svém seznamu argumentů. Tento způsob práce se ale v C++ nedoporučuje, je pozůstatkem stylu jazyka C. Jazyk C++ preferuje tzv. "zapouzdřenost" dat a s nimi pracujících funkcí do jednoho objektu, kde funkce jednoho objektu pracují s daty "svého" objektu a do jiných objektů "nevidí". Tento způsob programování se nazývá "objektovým programováním".
5/9 Autorem materiálu a všech jeho částí, není‐li uvedeno jinak, je Ing. Jiří Ilkiv. Dostupné z Metodického portálu www.rvp.cz, ISSN: 1802‐4785, financovaného z ESF a státního rozpočtu ČR. Provozuje Národní ústav pro vzdělávání, školské poradenské zařízení a zařízení pro další vzdělávání pedagogických pracovníků.
Ing. Jiří ILKIV VY_32_INOVACE_ICT_813
13.2. Definice funkce Definice funkce se pouští do nitra "černé skříňky" s úkolem definovat vnitřní procesy, jejichž výsledkem je vrácená hodnota. V deklaraci jsme se mohli dívat na funkci jako na továrnu z venku a viděli jsme jaké suroviny a v jakém pořadí vcházejí do továrny (argumenty funkce) a co z továrny vychází (vrácená hodnota). V definici vstoupíme dovnitř, do továrny, a naprogramujeme takové "výrobní" procesy, které z přivezených surovin (tj. z argumentů funkce) zajistí co nejefektivnější výrobu požadovaného výrobku (tj. 6
vrácenou hodnotu). Definici funkce uvádíme v projektu v Microsoft Visual Studiu zpravidla v souboru s koncovkou .cpp ve složce "Source Files" aktuálního projektu. Na obrázku vidíme složku "Source Files" projektu, která obsahuje dva soubory. A to soubor main.cpp a soubor definic funkcí funkce.cpp:
obr.2: umístění soubor definic funkcí v Microsoft Visual C++ projektu
Definice funkce se nachází, jak již bylo řečeno, v souboru s koncovkou ".cpp". V záhlaví tohoto souboru musíme za direktivou #include uvést název souboru deklarace. Tento název, je na rozdíl od systémových hlavičkových souborů, které jsou ohraničeny < >, ohraničen uvozovkami:
6
Některé definice funkcí, např. členské funkce generických tzv. "šablonových" tříd nelze uvádět při použití překladače jazyka C++ nepodporujícího klíčové slovo "export" v oddělených souborech *.cpp ale musí být uvedeny spolu s deklarací v *.h souboru.
6/9 Autorem materiálu a všech jeho částí, není‐li uvedeno jinak, je Ing. Jiří Ilkiv. Dostupné z Metodického portálu www.rvp.cz, ISSN: 1802‐4785, financovaného z ESF a státního rozpočtu ČR. Provozuje Národní ústav pro vzdělávání, školské poradenské zařízení a zařízení pro další vzdělávání pedagogických pracovníků.
Ing. Jiří ILKIV VY_32_INOVACE_ICT_813 #include
//systémový hlavičkový soubor
#include "funkce.h"
//hlavičkový soubor deklarace s názvem funkce.h
using namespace std; int sectiDveCisla( int X , int Y ){ int soucet = X + Y; return soucet; }
Na první pohled je zřejmé, že definice opisuje zcela přesně celou deklaraci (kromě koncového středníku). Poté následuje "tělo funkce", uzavřené mezi dvěma složenými závorkami { }. V těle funkce už konečně nacházíme trochu programování. Zde je totiž naprogramován samotný postup, algo‐ ritmus, kterým funkce získává svůj výsledek. Jakmile funkce dospěje k výsledku, vrací jej jako vrácenou hodnotu. V těle funkce můžeme definovat i další proměnné, které nám pomáhají řešit problém. Zde např. proměnnou int 7
součet. Takto definované proměnné existují pouze dočasně , jen po dobu volání funkce. Jakmile funkce skončí, tyto proměnné mizí a jejich hodnoty se ztrácí. Vrácenou hodnotu vytváří z výsledku příkaz return, následovaný výrazem, který obsahuje výsledek. Pokud máme funkci, která např. smaže obrazovku nebo pípne, zahraje melodii, změní nějaké hodnoty apod., aniž by vracela hodnotu, pak není příkaz return nutný:
void pipni(int kolikrat){ for(int i = 0; i
Příkaz return lze ale uvést i zde a to samotný, pouze ukončený středníkem: void pipni(int kolikrat){ for(int i = 0; i
Na příkladu funkce pipni() vidíme, že typ návratové hodnoty funkce, která nic nevrací je void. Funkcím, které nic nevrací, se v některých programovacích jazycích říká "procedury". Jazyk C++ název "procedura" nepoužívá. V C++ jsou to všechno prostě funkce, které buď vrací nebo nevrací hodnotu.
7
Výjimkou jsou tzv. "statické proměnné", které bez úhony přetrvají i období mezi jednotlivými voláními funkce přičemž si uchovávají svůj obsah.
7/9 Autorem materiálu a všech jeho částí, není‐li uvedeno jinak, je Ing. Jiří Ilkiv. Dostupné z Metodického portálu www.rvp.cz, ISSN: 1802‐4785, financovaného z ESF a státního rozpočtu ČR. Provozuje Národní ústav pro vzdělávání, školské poradenské zařízení a zařízení pro další vzdělávání pedagogických pracovníků.
Ing. Jiří ILKIV VY_32_INOVACE_ICT_813 Mohou existovat i funkce, které ke svojí práci nepotřebují argumenty, pak je seznam argumentů prázdný: void pipniJednou(){ cout << "\a"; return; }
Funkce mohou volat jiné funkce. V následujícím příkladu volá funkce pipni() funkci pipniJednou(): void pipni(int kolikrat){ for(int i = 0; i
Další příklad ukazuje funkci sectiTriCisla(), která volá několikrát funkci sectiDveCisla(): int sectiTriCisla(int A, int B, int C){ int soucet; soucet = sectiDveCisla(A,B); soucet = sectiDveCisla(soucet, C); return soucet; }
nebo v úspornějším (ale méně názorném) tvaru: int sectiTriCisla(int A, int B, int C){ return sectiDveCisla(sectiDveCisla(A,B), C); }
Funkce může vracet hodnotu příkazem return i z několika míst ve svém těle. Podívejme se na funkci dejMensi(),která vrací menší se svých dvou argumentů. Uvědomme si, že příkaz return vždy ukončuje provádění funkce :
int dejMensi(int r, int s){ if(r < s) return r;
//vrací 'r' a ukončuje funkci
return s;
//jinak vrací 's' a ukončuje funkci
}
8/9 Autorem materiálu a všech jeho částí, není‐li uvedeno jinak, je Ing. Jiří Ilkiv. Dostupné z Metodického portálu www.rvp.cz, ISSN: 1802‐4785, financovaného z ESF a státního rozpočtu ČR. Provozuje Národní ústav pro vzdělávání, školské poradenské zařízení a zařízení pro další vzdělávání pedagogických pracovníků.
Ing. Jiří ILKIV VY_32_INOVACE_ICT_813
13.3. Funkce main() Nejobvyklejší způsob volání funkcí v nepříliš rozsáhlých programech bývá z hlavni funkce main(). 8
Funkce main() je, jak víme, startovním bodem C++ programu. Ve většině případů se snažíme, aby funkce main() 9
zajišťovala veškerou komunikaci s uživatelem programu, tj. načtení hodnot, které uživatel zadá z klávesnice a také výpis získaných výsledků na monitor. Funkce volané funkcí main() pak zajišťují pouze "odbornou stránku" věci, tj. zpracování dat: #include #include "funkce.h" using namespace std; int main(){ //uživatelský vstup: cout << "Zadejte tri cisla: "; int prvni, druhe, treti; cin >> prvni >> druhe >> treti; //zpracování dat funkcemi: int soucet = sectiTriCisla(prvni, druhe, treti); double prumer = dejPrumerTriCisel(prvni, druhe, treti); //výstup na monitor: cout << "Soucet: " << soucet << endl; cout << "Prumer: " << prumer << endl; return 0; } Hlavní funkce main() zpravidla "obývá" sama soubor nazvaný obvykle main.cpp nebo hlavni.cpp. Ten je uložen ve složce "Souce Files" projektu. Podívejte se na obrázek obr.2, kde je soubor main.cpp ve společnosti dvou souborů definic List.cpp a Element.cpp právě ve složce "Souce Files". Funkce main() je jediná funkce v programu, která nemá deklaraci ale má pouze definici. Překladač jazyka C++ očekává, že funkce main() má vždy návratový typ int. Vrácená hodnota z funkce main() má význam pouze pro toho kdo funkci main() volá ‐ a tím volajícím je operační systém počítače (Windows, Linux). Z dávných dob jazyka C je zvykem, že pokud funkce main() proběhla korektně, vrací hodnotu 0, pokud byla ukončena nekorektně, třeba pokud nebyl nalezen potřebný datový soubor, vrací hodnotu ‐1. 10
Funkce main() může mít i argumenty , se kterými pak lze volat program z příkazového řádku operačního systému.
8
Grafické aplikace např. pro operační systém Windows startují, kromě jiných odlišností, ve funkci _tWinMain().
9 Pokud to nedělají specializované funkce. 10 //PROGRAM: test //Program zavoláme z příkazového řádku zadáním: C:> test ahoj karle #include using namespace std; int main(int argc, char* argv[]){ //argc je počet řetězců předaných v poli argv[], argv[] je pole předaných řetězců cout << "Vstupni radka ma " << argc << " argumentu." << endl; for(int i = 0; i < argc; i++) cout << "argument[" << i <<"] = " << argv[i] << endl;
return 0;
9/9 Autorem materiálu a všech jeho částí, není‐li uvedeno jinak, je Ing. Jiří Ilkiv. Dostupné z Metodického portálu www.rvp.cz, ISSN: 1802‐4785, financovaného z ESF a státního rozpočtu ČR. Provozuje Národní ústav pro vzdělávání, školské poradenské zařízení a zařízení pro další vzdělávání pedagogických pracovníků.