-
Funkce jsou zßkladem programovßnφ v C a C++. Funkce jsou Φßstφ k≤du odd∞lenΘ
od hlavnφho programu. Tyto Φßsti k≤du jsou volßny (provßd∞ny), kdy╛ je
zapot°ebφ provΘst jistou akci v programu. Nap°. m∙╛eme mφt funkci, kterß
p°ebφrß dv∞ hodnoty, provede s nimi jistΘ v²poΦty a vrßtφ v²sledek. Nebo
m∙╛eme mφt funkci p°ebφrajφcφ °et∞zec, rozd∞lφ jej a vracφ Φßst tohoto
°et∞zce. Nejjednodu╣╣φ typ funkce nemß parametry a vracφ void (co╛
znamenß, ╛e nevracφ nic). JinΘ funkce mohou mφt jeden nebo vφce parametr∙
a mohou vracet hodnotu. Ka╛d² program musφ mφt prßv∞ jednu funkci
se jmΘnem main (nebo WinMain)
oznaΦujφcφ vstupnφ bod programu. Funkce jsou obvykle deklarovßny jako prototypy
ve standardnφch nebo u╛ivatelsk²ch hlaviΦkov²ch souborech, nebo uvnit°
zdrojov²ch soubor∙. Funkce jsou definovßny ve zdrojov²ch souborech programu
nebo ve zp°φstupn∞n²ch knihovnßch. Nedefinujφcφ deklarace funkcφ pou╛φvajφ
formßt funkΦnφho prototypu poskytujφcφ p°ekladaΦi detailnφ informace o
parametrech a tφm mu umo╛≥ujφ provΘst kontrolu poΦtu parametr∙, kontrolu
typ∙ parametr∙ a pou╛itφ p°φpadn²ch automatick²ch p°evod∙ typ∙. Prototypy
funkcφ se v C++ musφ pou╛φvat a doporuΦuje se je pou╛φvat i v C.
V jazyku C mohla b²t funkce p∙vodn∞ deklarovßna bu∩ implicitn∞ sv²m
v²skytem ve funkΦnφm volßnφ, nebo explicitn∞ zßpisem:
typ fce();
kde typ urΦuje nßvratov² typ funkce (implicitn∞ int),
p°iΦem╛ funkce m∙╛e vracet libovoln² typ s v²jimkou pole nebo funkce. Tento
styl deklaracφ v╣ak neumo╛≥uje, aby p°ekladaΦ vedle kontroly nßvratovΘho
typu provßd∞l takΘ kontrolu poΦtu a typ∙ parametr∙ funkce. Tento problΘm
byl vy°e╣en zavedenφm prototypu funkce. Prototyp funkce zapisujeme takto:
typ fce(seznam-deklaracφ-parametr∙);
Deklarace specifikujφ typ ka╛dΘho parametru. P°ekladaΦ tyto informace
pou╛φvß pro kontrolu sprßvnosti volßnφ funkce. V n∞kter²ch p°φpadech je
p°ekladaΦ rovn∞╛ schopen p°evΘst typ parametru na po╛adovan² typ. Podφvejte
se na nßsledujφcφ Φßst programu:
long lmax(long v1,
long v2); // prototyp
void main(int argc,
char **argv)
{
int limit
= 32;
char ch =
'A';
long mval;
mval = lmax(limit,
ch);
// volßnφ funkce
}
Proto╛e p°ekladaΦ znß prototyp funkce lmax, jsou parametry funkce
(limit a ch) nejprve pou╛itφm standardnφch pravidel p°evedeny
na typ long (po╛adovan² typ parametr∙) a teprve potom jsou p°edßny
funkci. Bez pou╛itφ prototypu, p°ekladaΦ neznß datovΘ typy parametr∙ a
neprovßdφ ╛ßdn² p°evod. Funkci jsou tedy p°edßny limit a ch
jako typy int a char, co╛ funkce lmax neoΦekßvß a
dostßvßme se do problΘm∙.
Prototypy funkcφ takΘ p°ispφvajφ k lep╣φ dokumentaci programu. Nap°.
funkce strcpy (kopφrovßnφ °et∞zce znak∙) mß dva parametry: zdrojov²
a cφlov² °et∞zec. Otßzkou je, kter² je zdrojov² a kter² je cφlov²? Prototyp
funkce
char *strcpy(char
*cil, const char *zdroj);
v╣e objasnφ. JmΘna parametr∙ v prototypu majφ pouze dokumentaΦnφ ·Φel.
Prototypy funkcφ zapisujeme v hlaviΦkov²ch souborech nebo na zaΦßtku zdrojovΘho
textu programu.
Definice funkce obsahuje t∞lo funkce, tj. k≤d, kter² se bude p°i volßnφ
funkce provßd∞t. Deklarace formßlnφch parametr∙ majφ stejn² zßpis jako
deklarace prom∞nn²ch. V C++ je mo╛no v deklaraci parametr∙ uvΘst implicitnφ
hodnoty parametr∙. Parametry s implicitnφmi hodnotami musφ b²t poslednφmi
paramery. V deklaracφch parametr∙ je mo╛nΘ pou╛φt i modifikßtor const.
Definice funkce je popsßna na nßsledujφcφm obrßzku:
Pokud funkce nevracφ ╛ßdnΘ informace, pak jejφ typ je void.
Funkce typu void majφ p°φkaz return bez v²razu urΦujφcφho
vrßcenou hodnotu.
P°i volßnφ funkce jsou skuteΦnΘ parametry funkce uvedeny ve stejnΘm
po°adφ jako parametry v definici funkce. PoΦet parametr∙ musφ souhlasit.
Typy parametr∙ musφ b²t kompatibilnφ do tΘ mφry, aby mohly b²t p°evedeny.
Pokud uvedeme definici funkce d°φve ne╛ funkci pou╛ijeme, pak prototyp
funkce nenφ nutno uvßd∞t.
-
Pou╛itφ funkce ukazuje nßsledujφcφ konzolovß aplikace:
#include <iostream.h>
#include <conio.h>
#pragma hdrstop
//---------------------------------------------------------------------
#pragma argsused
int nasob(int, int);
void zobrazVysledek(int);
int main(int argc,
char **argv)
{
int x, y,
vysledek;
cout <<
endl << "Zadej prvnφ hodnotu: ";
cin >> x;
cout <<
"Zadej druhou hodnotu: ";
cin >> y;
vysledek =
nasob(x, y);
zobrazVysledek(vysledek);
cout <<
endl << endl << "Stiskni libovolnou klßvesu ... ";
getch();
return 0;
}
int nasob(int x,
int y)
{
return x*y;
}
void zobrazVysledek(int
vysl)
{
cout <<
"V²sledek je: " << vysl << endl;
}
Tento program vy╛aduje zadßnφ dvou Φφsel, volß funkci nasob
k vynßsobenφ zadan²ch hodnot a potom volß funkci zobrazVysledek
k zobrazenφ v²sledku. Prototypy t∞chto funkcφ jsou uvedeny na zaΦßtku programu
(p°ed funkcφ main). V prototypech je uveden pouze nßvratov² typ,
jmΘno funkce a datovΘ typy parametr∙ funkce. Toto je minimßlnφ po╛adavek
na deklaraci funkce. Je-li to zapot°ebφ, prototyp funkce m∙╛e obsahovat
jmΘna parametr∙, kterΘ mohou b²t pou╛ity k dokumentovßnφ Φinnosti funkce.
Nap°. deklarace funkce nasob m∙╛e b²t zapsßna takΘ takto:
int nasob(int prvniCislo,
int druheCislo);
V na╣em p°φpad∞ je jasnΘ co funkce d∞lß a nenφ zapot°ebφ ╛ßdnß dokumentace.
Definice tΘto funkce je takΘ jednoduchß. Na╣e funkce m∙╛e b²t volßna n∞kolika
zp∙soby. Mohou ji b²t p°edßny konstanty, hodnoty prom∞nn²ch a v²sledek
m∙╛e b²t takΘ p°edßn jinΘ funkci. Nßsleduje n∞kolik p°φklad∙ volßnφ tΘto
funkce:
vysledek = nasob(5,
2);
vysledek = nasob(x,
y);
zobrazVysledek(nasob(x,
5));
nasob(3, x);
V poslednφm p°φklad∞ vrßcenß hodnota nenφ pou╛ita. Ignorovßnφ vrßcenΘ
hodnoty je v na╣em p°φpad∞ nesmyslnΘ, ale v n∞kter²ch p°φpadech je to Φasto
pou╛φvanΘ. Je mnoho funkcφ provßd∞jφcφch jistΘ akce a vrßcenß hodnota indikuje
stav volßnφ. Pokud tato hodnota nenφ d∙le╛itß pro nß╣ program, pak ji m∙╛eme
ignorovat. Nap°. v na╣ich programech jsme zatφm ignorovali hodnotu vracenou
funkcφ getch (ASCII hodnota stisknutΘ klßvesy).
Funkce m∙╛e volat jinΘ funkce. Funkce m∙╛e takΘ volat sama sebe. Toto
naz²vßme rekurze.
-
Nßsledujφcφ konzolovß aplikace zji╣╗uje, zda zadanΘ Φφslo je prvoΦφslo.
Zda se jednß o prvoΦφslo urΦuje funkce je_prvocislo. Tato funkce
pou╛φvß pomocnou funkci zji╣╗ujφcφ d∞litelnost Φφsel. Ob∞ tyto funkce majφ
v programu uveden prototyp. Prostudujte si tento v²pis, program vyzkou╣ejte
a sna╛te se pochopit jak jednotlivΘ funkce pracujφ.
int je_prvocislo(int);
int je_delitelno(int,
int);
int main(int argc,
char **argv)
{
int n;
cout <<
"Zadej p°irozenΘ Φφslo: ";
cin >> n;
cout <<
"Φφslo " << n << (je_prvocislo(n) ? " je" : " neni")
<< " prvoΦφslo." << endl;
getch();
return 0;
}
int je_prvocislo(int
n)
{
for (int i
= 2; i*i <= n; i++)
if (je_delitelno(n, i)) return 0;
return 1;
}
int je_delitelno(int
n, int m)
{
return !(n
% m);
}
-
Nßsledujφcφ funkce urΦuje nejv∞t╣φ spoleΦn² d∞litel dvou p°irozen²ch Φφsel.
Pou╛ijte tuto funkci v konzolovΘ aplikaci, kde p°eΦtete Φitatel a jmenovatel
zlomku a provedete p°φpadnΘ zkrßcenφ zlomku. V programu uve∩te i prototyp
tΘto funkce.
int nsd(int a, int
b)
{
int pom;
while (b)
{
pom = a % b;
a = b;
b = pom;
}
return a;
}
-
Napi╣te funkci vypisujφcφ °ßdek obsahujφcφ n znak∙ z. n
a z jsou parametry funkce. Tuto funkci pou╛ijte v programu pro v²pis
nap°. 50-ti znak∙ podtr╛enφ a 20-ti znak∙ hv∞zdiΦek.
-
P°ejdeme op∞t k aplikacφm GUI. Vytvo°φme aplikaci, kde na formulß°i budou
t°i editaΦnφ ovladaΦe (vyprßzdnφme je a p°ed n∞ umφstφme texty ?Prvnφ operand:?,
?Druh² operand:? a ?V²sledek:?) a tlaΦφtka ?SouΦet?, ?Rozdφl?, ?SouΦin?
a ?Podφl?. Obsluha udßlosti stisku tlaΦφtka ?SouΦet? bude tvo°ena p°φkazy:
int x, y;
x = Edit1->Text.ToInt();
y = Edit2->Text.ToInt();
Edit3->Text = AnsiString(x
+ y);
Vytvo°te obsluhy i pro ostatnφ tlaΦφtka a program vyzkou╣ejte.
-
Do p°edchozφ aplikace p°idßme je╣t∞ dal╣φ editaΦnφ ovladaΦ, ve kterΘm budeme
poΦφtat poΦet proveden²ch v²poΦt∙ (vyprßzdnφme jej a p°ed n∞j umφstφme
text ?PoΦet proveden²ch v²poΦt∙:?). Pro poΦφtßnφ proveden²ch v²poΦt∙ musφme
zavΘst globßlnφ prom∞nou, nazveme ji nap°. Pocet (globßlnφ prom∞nnΘ
deklarujeme mimo funkce; je nutno ji deklarovat p°ed prvnφ funkcφ, ve kterΘ
ji pou╛φvßme). Do v╣ech obsluh stisknutφ tlaΦφtek p°idßme p°φkazy:
Pocet++;
Edit4->Text = AnsiString(Pocet);
Bylo by vhodnΘ na╣i prom∞nnou Pocet na poΦßtku v²poΦtu vynulovat.
M∙╛eme to provΘst tak, ╛e jejφ deklaraci spojφme s inicializacφ, tzn. p°ed
prvnφ obsluhu vlo╛φme:
int Pocet = 0;
-
Jist∞ jste si pov╣imli, ╛e kdy╛ stisknete n∞kterΘ tlaΦφtko a nemßte zadanΘ
operandy je signalizovßna chyba. Na zaΦßtku obsluh stisku tlaΦφtek budeme
testovat, zda oba operandy jsou zadßny. Toto testovßnφ je nutno provßd∞t
ve v╣ech obsluhßch stisku tlaΦφtek a tedy vytvo°φme funkci, kterß otestuje
editaΦnφ ovladaΦ zadan² parametrem funkce (pokud editaΦnφ ovladaΦ je prßzdn²
vrßtφ true, jinak vrßtφ false). Tato funkce bude vypadat
takto:
bool NeniHodnota(TEdit
*EditOvl){
if (EditOvl->Text
== "") {
EditOvl->Color = clRed;
EditOvl->Text = "Zadej hodnotu";
EditOvl->SetFocus();
return true;
}
else {
EditOvl->Color = clWindow;
return false;
}
}
Parametr funkce je typu ukazatel na TEdit,
co╛ je typ editaΦnφho ovladaΦe (v╣echny typy komponent zaΦφnajφ pφsmenem
T) a jako skuteΦn² parametr tedy budeme moci pou╛φt Edit1
i Edit2. Pokud v editaΦnφm ovladaΦi nenφ zapsßn
╛ßdn² text, je zm∞n∞na barva ovladaΦe na Φervenou a je zde vypsßn text
?Zadej hodnotu. P°φZadej EditOvl->SetFocus();
zajistφ vybrßnφ testovanΘho editaΦnφho ovladaΦe a m∙╛eme tedy do n∞j ihned
zapisovat hodnotu. Pokud editaΦnφ ovladaΦ nenφ prßzdn², pak je zm∞n∞na
jeho barva na normßlnφ barvu okna (clWindow). Tuto funkci musφme je╣t∞
vyvolat na zaΦßtku v╣ech obsluh stisk∙ tlaΦφtek. Na zaΦßtek v╣ech t∞chto
obsluh tedy p°idßme p°φkaz:
if (NeniHodnota(Edit1)
|| NeniHodnota(Edit2)) return;
Prove∩te v²╣e uvedenΘ zm∞ny pro v╣echna tlaΦφtka a vyzkou╣ejte. Nenφ
to ale ideßlnφ °e╣enφ, nebo╗ nezaji╣╗uje aby v editaΦnφm ovladaΦi byla
zapsßna Φφselnß hodnota.
-
V dal╣φ aplikaci se seznßmφme s pou╛φvßnφm komponenty Timer
(ΦasovaΦ - je ji mo╛no pou╛φt k definovßnφ ΦasovΘho intervalu). Na formulß°
umφstφme tuto komponentu (je na strßnce System Palety komponent).
Jedna z vlastnostφ tΘto komponenty urΦuje Φasov² interval v milisekundßch
(tato vlastnost se jmenuje Interval). Do programu
vlo╛φme deklaraci globßlnφ prom∞nnΘ X typu bool a vytvo°φme
obsluhu udßlosti OnTimer ΦasovaΦe s p°φkazy:
if (X) Color = clRed;
else Color = clGreen;
X = !X;
Zjist∞te, co provßdφ tato aplikace.
-
Vytvo°te aplikaci, ve kterΘ se pokusφte simulovat hßzenφ hracφ kostkou.
Ka╛dou sekundu generujte hod a jeho v²sledek zobrazte na formulß°i (Φφseln∞).
Inicializaci generßtoru nßhodn²ch Φφsel prove∩te v obsluze udßlosti OnCreate
formulß°e.
NovΘ pojmy:
-
Funkce je Φßst k≤du (odd∞lenß od hlavnφho programu), kterß provßdφ
jednoduchΘ, dob°e definovanΘ akce.
-
Parametr je hodnota p°edßvanß funkci, kterß ji pou╛ije ve sv²ch
operacφch.
-
Prototyp je deklarace funkce, kterß je uvedena p°ed definicφ funkce.
-
Definice funkce uvßdφ p°φkazy tvo°φcφ funkci.
-
Volßnφ funkce je vyvolßnφ p°φkaz∙ tvo°φcφch funkci.
-
Rekurze je proces, ve kterΘm funkce volß sama sebe.
-
Lokßlnφ prom∞nnß je prom∞nnß deklarovanß uvnit° funkce (existuje
pouze do nßvrazu z funkce).
-
Globßlnφ prom∞nnß je prom∞nnß deklarovanß mimo funkci (existuje
do ukonΦenφ programu).