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.

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

Registrací souhlasíte s provozními podmínkami a zásadami ochrany osobních údajů.

Nebo se registrujte pomocí:

3/12