Funkce a prototypy v C++

C++ Základní konstrukce C++ Funkce a prototypy v C++

Funkce v C++
Bez funkcí se v programování neobejdete. Jsou to vlastně algoritmy, pomocí kterých pracujete s daty. Určitě jste v matematice brali funkce, tak víte že musí mít určitý předpis, pomocí kterého se dosáhne požadovaného výsledku. Do dané funkce se pak dosadí data (jako parametry), s kterými je poté uvnitř nějakým způsobem manipulováno. Tak to by mohla být stručná definice pojmu funkce v jazyce C++, ale teď už konkrétněji.

Tak dejme tomu, že chcete vytvořit funkci, která vám spočítá druhou mocninu nějakého čísla. Tato funkce by mohla vypadat třeba takto:

//lekce4.cpp
#include <iostream>
using namespace std;

int Umocni(int x)
{
    return x*x;
}

int main()
{
    cout << "Zadejte cislo: ";
    int x;
    cin >> x;
    cout << "Druha mocnina cisla " << x <<" je "
         << Umocni(x) << endl;
    return 0;
}

Tak a funkce je na světě:) Jak jste si jistě všimli, nese název Umocni(), který dokonale vystihuje její účel. Podívejte se ještě jednou na definici funkce:

int Umocni(int x)
{
    return x*x;
}

První řádka se nazývá hlavička funkce. Klíčové slovo int před názvem funkce symbolizuje typ návratové hodnoty funkce, tedy typ dat, který je vracen ve funkcí pomocí příkazu return. Zde se jedná konkrétně o celé číslo. Za názvem funkce následují kulaté závorky se seznamem parametrů oddělených čárkou. Tato funkce má pouze jeden parametr typu int. Hlavička funkce je následována tělem funkce, které je uzavřeno do složených závorek. Do těla se zapisují veškeré příkazy, které má funkce vykonat. V tomto případě je zde příkaz xx*, jehož výsledkem je celé číslo, které je místo tohoto výrazu xx* jakoby vnitřně nahrazeno a vráceno příkazem return.

Určitě vám to teď připomíná funkci main(). Je to úplně to samé...

Vytváření funkčních prototypů

Funkční prototypy jsou další věcičkou, která je pro vlastní funkce hodně důležitá. No vlastně ani tak ne pro funkce, jako spíše pro kompilátor. Prorotyp mu totiž říká všechny potřebné informace o funkci, jako je její jméno, návratovou hodnotu a typy parametrů. Jednoduše ho můžete vytvořit tak, že zkopírujete hlavičku funkce a přidáte středník. V předchozím příkladě byl tento prototyp zároveň definicí. Podívejme se tedy, jak můžeme naší funkci upravit, aby byl prototyp vyžadován:

//lekce4.cpp
#include <iostream>
using namespace std;

int Umocni(int x); //Prototyp funkce


int main()
{
    cout << "Zadejte cislo: ";
    int x;
    cin >> x;
    cout << "Druha mocnina cisla " << x <<" je "
         << Umocni(x) << endl;
    return 0;
}

int Umocni(int x)
{
    return x*x;
}

Pokud by zde prototyp nebyl, kompilátor by nahlásil chybu, že nebyl deklarován identifikátor Umocni. Onou deklarací se rozumí samotný prototyp funkce. Ono je to i celkem logické. Vždyť používáte funkci, o které kompilátor normálně nic neví, neví jaké má očekávat parametry, jejich počet, ani zda popř. jakou vrací hodnotu. Potřebuje tedy znát prototyp této funkce. Tento se umisťuje většinou před definici funkce main(), nebo, ještě častěji, do hlavičkových souborů (ty jsou pak vkládány pomocí directivy #include, jak už víte).

Ukažme si ale ještě jeden případ - ten se používá nejčastěji. Mějme tři soubory - hlavní, s funkcí main(), hlavičkový - s deklarací (neboli prototypem) funkce Umocni, a soubor s její definicí.

Hlavičkový soubor funkce Umocni():

//umocni.h
int Umocni(int x);

Soubor s definicí funkce Umocni():

//umocni.cpp
int Umocni(int x)
{
    return x*x;
}

No a konečně hlavní zdrojový soubor, kde dáme vše dohromady:

//main.cpp
#include <iostream>
#include "umocni.h"
using namespace std;

int main()
{
    cout << "Zadejte cislo: ";
    int x;
    cin >> x;
    cout << "Druha mocnina cisla " << x <<" je "
         << Umocni(x) << endl;
    return 0;
}

Určitě jste si všimli že přibyla jedna directiva #include, která vloží hlavičkový soubor umocni.h - zpřístupní tím deklaraci funkce Umocni(). Pozorný čtenář se jistě pozastavil nad tím, proč je zde soubor v uvozovkách a ne ve zkosených závorkách. Asi bych to měl vysvětlit, jedná se o docela důležitou věc.

Takže popořadě. Pokud používáte nějaké vývojové prostředí, jsou v něm definovány určité absolutní cesty k některým důležitým souborům - ať už hlavičkovým, tak třeba zdrojovým. Ale k čemu nám tahle informace vlastně je? No je to o tom, že pokud použijeme verzi se zkosenými závorkami, tak první věc, kterou preprocesor při zpracování této direktivy udělá je, že prohledá právě tyto cesty. Pokud v žádné z těchto definovaných cest daný soubor nenalezne, nahlásí chybu. U druhé varianty, té s uvozovkami, je to jinak. Zde přímo určujete cestu, ať už absolutně, nebo relativně k umístění souboru, ve kterém je tato direktiva umístěna. Pokud preprocesor soubor nenajde, začne prohledávat cesty definované vývojovým prostředím, viz. výše. Možná by se zde hodila menší poznámka - pokud zadáváte cestu, používejte pro znak lomítka (\) jeho escape sekvenci (\\) - tedy dvě lomítka za sebou. Je to proto že lomítko je speciální znak, který uvozuje escape sekvence. Vysvětlení si necháme na jindy, zatím postačí, když místo jednoho lomítka použíjete dvě.:)


 

  Aktivity (3)

Článek pro vás napsal Jiří Pipošiar
Avatar
Moc toho tady o sobě prozrazovat nebudu, raději:)) Takže momentálně žiju v Klatovech(velkoměsto v západních Čechách), a 22.5.2003 jsem zde i odmaturoval na střední průmyslové škole. No a novinka - byl jsem přijat na Západočeskou univerzitu - Faku...

Jak se ti líbí článek?
Celkem (1 hlasů) :
55555


 


Miniatura
Všechny články v sekci
Základy C++
Miniatura
Následující článek
Pokročilá práce s konzolí v C++

 

 

Komentáře

Avatar
Tlapka
Člen
Avatar
Tlapka:

Chtěla bych se zeptat na ten princip s těmi více soubory. Už jsem tento způsob viděla, ale dvě věci na něm nechápu:

  1. Jak program najde definici (funkci včetně těla), když soubor "umocni.cpp" není nikde includován (includován je jen "umocni.h")?
  2. Proč se používá tento způsob? Nebylo by lepší psát funkce jen jednou, jak je tomu v prvním případě a ušetřit si tak vytváření dalších dvou souborů navíc? Nebo v případě OOP vytvořit jeden soubor pro jednu třídu, jak je tomu např. v Javě?

Předem díky za odpovědi. ;-)

 
Odpovědět 16.10.2014 0:19
Avatar
MrPabloz
Člen
Avatar
Odpovídá na Tlapka
MrPabloz:
  1. Překládač automaticky pospojuje .h a .cpp nebo .obj co k sobě patří = stejný název. Takže tohle dělá překládač :)
  2. Protože jsou určité návrhové vzory, které se používají, pro c++ byl vymyšlen tenhle, chtělo se myslím omezit používání transakčnímu skriptu a měl být přehledný kod. Ale je tu ještě jeden důvod, pokud dáš někome část svého projektu, např. vytvoříš knihovnu, která má funkce a chceš, aby nikdo nevěděl jak vypadají, pospleš dotyčnému obj soubor, zkompilovan z .cpp, ale nevěděl by pak nikdo, jak to použít, proto máš hlavičkový soubor, který jen popisuje syntaxe atd. Tedy neví nikdo nic o funkčnosti, jen ví názvy fci a co vrací a jaké má vstupy, tohle je důležitější než vzory :) a proč ne jak Java? Protože Java si to umí přečíst a nabídne použití v intelisense, ale tohle dřív c++ neumělo :)
Odpovědět 16.10.2014 9:24
Harmonie těla a duše, to je to, oč se snažím! :)
Avatar
coells
Redaktor
Avatar
Odpovídá na Tlapka
coells:
  1. při překladu dáš cestu k .cpp souborům přímo překladači, includované soubory už dohledá sám

gcc -o program.o *.c *.cpp
tím řekneš překladači, že chceš přeložit všechny soubory s danými koncovkami a includované soubory už si dohledá sám
pokud pracuješ v IDE, vyvolá prostředí za tebe takový příkaz a postará se o celou konfiguraci samo

  1. protože C a C++ jsou jednoprůchodové překladače

to znamená, že než se můžeš odkázat na nějakou funkci nebo proměnnou nebo typ, musíš je nejprve deklarovat
k tomu slouží headery, kde máš všechny potřebné deklarace, abys mohla prolinkovat jednotlivé knihovny

 
Odpovědět  +1 16.10.2014 13:00
Avatar
Tlapka
Člen
Avatar
Odpovídá na coells
Tlapka:

Aha, díky vám oběma, vypadá to, že se toho budu muset ještě hodně učit. Dík, hezké vysvětlení. ;-)

 
Odpovědět 16.10.2014 22:07
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 4 zpráv z 4.