Prototypy funkcí
Překladač čte váš program shora dolů, podobně jako vy čtete knihu. Když narazí na volání funkce, musí už funkci znát: její název, co dostává a co vrací. Proto jsme funkce zatím definovali nad main. Tento program má funkci až pod main:
#include <stdio.h>
int main(void) {
pozdrav();
return 0;
}
void pozdrav(void) {
printf("Ahoj!\n");
}Program se nepřeloží:
main.c:4:5: error: call to undeclared function 'pozdrav'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
4 | pozdrav();
| ^
main.c:8:6: error: conflicting types for 'pozdrav'
8 | void pozdrav(void) {
| ^
main.c:4:5: note: previous implicit declaration is here
4 | pozdrav();
| ^
2 errors generated.Začněte první chybou. Na řádku 4 volá main funkci pozdrav, která ještě nebyla deklarovaná (ohlášená): nic nad řádkem 4 překladači neřeklo, že taková funkce existuje. Zbytek řádku říká, že od verze C99 z roku 1999 jazyk C nepovoluje takzvané implicitní deklarace funkcí. Velmi staré překladače totiž odhadovaly, jak neznámá funkce vypadá, a často se spletly. Druhá chyba, conflicting types (neslučitelné typy), je jen důsledkem té první: překladač si na řádku 4 udělal vlastní odhad (říká to řádek s note) a skutečná funkce na řádku 8 mu neodpovídá. Když opravíte první chybu, zmizí i druhá.
Opravit to jde dvěma způsoby. První znáte: celou funkci přesunete nad main. Druhým je prototyp funkce nad main: první řádek funkce, za kterým je místo těla středník:
#include <stdio.h>
void pozdrav(void);
int main(void) {
pozdrav();
return 0;
}
void pozdrav(void) {
printf("Ahoj!\n");
}Tento program vypíše:
Ahoj!Prototyp void pozdrav(void); je deklarace funkce. Říká překladači: existuje funkce pozdrav, nic nedostává, nic nevrací a její definice přijde později. To překladači stačí, aby volání zkontroloval. Prototyp musí odpovídat definici: stejný návratový typ, název i obsah závorek. A definice v programu opravdu být musí: s prototypem a bez definice se program nespustí a chybová hláška končí slovy undefined symbol: pozdrav, což znamená, že chybí tělo funkce pozdrav.
Proč psát prototypy? V dlouhém programu fungují prototypy nahoře jako obsah knihy: všechny funkce vidíte na první pohled a hned za nimi může být main. A prototypy ve skutečnosti používáte už od první lekce, aniž byste o tom věděli. Soubor stdio.h je hlavičkový soubor: obsahuje prototypy funkce printf a dalších funkcí z knihovny, tedy sbírky hotových funkcí, která k jazyku C patří. #include <stdio.h> vloží jeho obsah do vašeho programu, a tak překladač zná printf dřív, než ji zavoláte. Stejně tak string.h deklaruje strlen a ctype.h deklaruje toupper.
V tomto kurzu budeme většinou psát celé funkce nad main, protože je to jednodušší. Až ale v nějakém programu uvidíte prototyp, budete vědět, co to je.
Jak psát:
Pokyny
Program se nepřeloží, protože main volá funkci vypis_nazev, která je definovaná až pod ní. Funkci nepřesouvejte. Místo toho nad main přidejte její prototyp. Program pak vypíše název hry a Hru spustíte tlačítkem Start.
Pod funkci vypis_nazev napište funkci void vypis_rozlouceni(void), která vypíše Díky za hru!, a nad main pod první prototyp přidejte její prototyp.
Na konci main, před return 0;, zavolejte vypis_rozlouceni. Program vypíše:
VESMÍRNÝ ZÁVOD
==============
Hru spustíte tlačítkem Start.
Díky za hru!Začněte programovat zdarma
3/12