Funkce
Funkce jsou stavebním kamenem jazyka C. V tomto článku se seznámíme se základem práce s funkcemi.
Deklarace funkce
V deklaraci funkce musíme určit, jak se bude funkce chovat navenek. Musíme určit jméno funkce, vstupní parametry a návratovou hodnotu.
int secti (int a, int b)
{
return a + b;
printf("%d", a + b); // neprovede se
}
// ...
int c = secti(2, 3); // volání funkce, v proměnné c bude 5
Ve výpisu kódu jsme definovali funkci. Jak vidíme, na rozdíl od Pascalu v jazyce C není vyhrazené klíčové slovo pro funkci. Hlavička funkce se skládá pouze z návratového typu, jména a seznamu parametrů oddělených čárkami v kulatých závorkách. Zde tedy máme funkci secti (jména smějí obsahovat pouze alfanumerické znaky, podtržítka a první znak nesmí být číslice), která vrací celočíselnou hodnotu a přebírá celkem dva parametry typu int
, které jsme pojmenovali a a b. Jelikož jsme vytvořili funkci, která má vracet hodnotu, musíme zajistit její vyplnění. Zavoláním return
okamžitě ukončíme provádění funkce a vrátíme výsledek výrazu zapsaný za ním. printf()
se tedy nikdy neprovede.
V jazyce Pascal existovalo speciální označení pro funkci, která nic nevracela – procedura. Toto označení se v jazyce C nepoužívá, pouze označíme, že je návratový typ prázdný. K tomu je určen speciální typ void
. Tento typ značí prázdnou hodnotu, hodnotu bez typu. Procedura v jazyce C tedy vypadá následovně:
void vypis_hello (void)
{
printf("hello world\n");
return; // není nutné
}
// ...
vypis_hello();
Vytvořili jsme funkci, která nic nevrací, nebo-li proceduru. Pokud někdy potřebujeme ukončit vykonávání procedury předčasně, zavoláme return
bez výrazu. V našem příkladu toto není nutné, protože procedura stejně končí. Za povšimnutí stojí také to, že i když funkce nepřejímá žádné parametry, musíme napsat kulaté závorky. Uvnitř závorek by mělo být podle standardu buď void
, nebo nic. Standard C99 povoluje jen první možnost. Pokud voláme proceduru, musíme též napsat za název kulaté závorky. Pokud je vynecháme, funkce se nezavolá, ale překladač nás neupozorní. V sekci ukazatele si vysvětlíme proč.
Rekurze
V jazyce C lze bez problému využít rekurzi. Stačí pouze zavolat funkci samu v sobě. Je samozřejmě na nás, abychom zajistili konečnost takového zápisu.
void vypis_radu (int cislo)
{
if (cislo < 0) return;
printf("%d\n", cislo);
vypis_radu(cislo - 1);
}
// ...
vypis_radu(10);
Tento kód vypíše velmi neobratně čísla od deseti do nuly. Rekurze má typicky ukončovací podmínku, v tomto případě je to test zápornosti předaného parametru. Na řádce pět voláme v těle funkce tuto funkci znovu s jiným parametrem. V tuto chvíli se vyhodnocování původní funkce přeruší, vykoná se vnořená funkce a poté se vykonávání vnější funkce obnoví. Tento kód stejně jako většina ostatních případů rekurze, lze mnohem efektivněji přepsat za pomoci cyklu. Zde je uveden pro ilustraci.
Funkce main()
Už v prvním programu jsme potřebovali funkci main()
. Tato funkce je vstupním bodem programu, proto musí být v každém programu právě jednou! Její hlavička je poměrně komplikovaná, její účel je ale zřejmý.
int main (int argc, char **argv)
int main (void)
Dříve jsme se setkali jen s prvním typem hlavičky. Toto je tzv. plná definice funkce main()
. Konzolové aplikace, jako je např. překladač GCC, mohou měnit svoje chování v závislosti na předaných parametrech příkazové řádky. Tyto parametry pak program obdrží právě ve dvou parametrech funkce main()
. První parametr říká, kolik celkem parametrů jsme obdrželi, druhý parametr je seznam řetězců, ve kterém jsou postupně uložené všechny parametry. V případě, že nemáme o tyto parametry zájem, můžeme využít druhou formu zápisu.
Návratová hodnota funkce main()
představuje možnost, jak oznámit terminálu, že program skončil v pořádku, či s chybou. Standardně je hodnota EXIT_SUCCESS
(definovaná v souboru stdlib.h
většinou jako nula) považována za signalizaci správného ukončení programu. V případě předání EXIT_FAILURE
došlo při běhu programu k chybě.
#include <stdio.h>
int main (int argc, char **argv)
{
int i;
for (i = 0; i < argc; i++)
{
puts(argv[i]);
}
return 0;
}
Tento program vypíše všechny předané parametry. Máme-li program přeložen pod jménem parametry a zavoláme ho z terminálu v následující podobě
./parametry parametr1 --parametr2 par3
obdržíme výpis
./parametry
parametr1
--parametr2
par3
Všimněme si, že první parametr není parametr1, ale ./parametry, tedy forma, jakou spouštíme program. To se může někdy hodit. První skutečný parametr má tedy index jedna a ne nula, jak bychom očekávali. Parametry se nijak neupravují a předávají se s pomlčkami i jiným formátováním. Terminál je pouze rozseká podle mezer mezi nimi. Je na programátorovi, aby si parametry sám zpracoval.