× Aktuálně z oboru

SHIELD Experience Upgrade 7 – méně hledání a více zábavy [ clanek/2018052902-shield-experience-upgrade-7-mene-hledani-a-vice-zabavy/ ]
Celá zprávička [ clanek/2018052902-shield-experience-upgrade-7-mene-hledani-a-vice-zabavy/ ]

C++ - 6. lekce

[ http://programujte.com/profil/1483-lukas-chury/ ]Google [ https://plus.google.com/101446994797551111026?rel=author ]       [ http://programujte.com/profil/20356-josef-vitu/ ]Google [ ?rel=author ]       13. 4. 2005       71 222×

  • funkce
  • definice funkce
  • vytváření prototypů
  • volání funkce
  • parametry funkcí a předávání hodnotou
  • násobné parametry
  • úkol č. 6

Funkce – programové moduly v C++

C++ poskytuje velikou knihovnu užitečných f-cí, ale skutečné potěšení nastává při psaní vlastních f-cí. Abyste uměli používat f-ce, musíte udělat následující:

  1. Definici funkce
  2. Prototyp funkce
  3. Vyvolat funkci

Jestliže používáte knihovní funkci, tak již byla definována a překompilována. Například knihovní f-ce cstring zahrnuje f-ci strlen() k nalezení délky řetězce. cstring obsahuje i další f-ce, ale takto vyvolaná knihovní f-ce vám poté dovolí kdykoliv vyvolat f-ci strlen() ve vašem programu.

Definice funkce

Funkce můžeme rozdělit na dva druhy – funkce bez návratové hodnoty, funkce s návratovou hodnotou. Funkce bez návratové hodnoty se nazývají f-ce typu void a mají následující obecný tvar:


    void jméno_funkce(seznam_parametrů)
    {
        příkaz(y)
        return;        // nepovinné
    }

Pochopte tuto f-ci tak, že když ji zavoláte, udělá to, co v ní napíšete. seznam_parametrů zde určuje typ a počet parametrů předaných f-ci, tedy jaké hodnoty jí předáte v době volání. Nepovinný příkaz return zde ukazuje na konec f-ce. F-ce bez návratové hodnoty používáme, když chceme například provést nějaký cyklus (neboli f-ce bez návratové hodnoty nám slouží ke zpřehlednění samotného kódu v main). F-ci odtud pak již jen zavoláme a je jedno, zda bude součástí souboru, či si ji vyvoláme jako externí soubor. Například definice f-ce na vytištění deseti pozdravů:


    void pozdrav(int n)        //funkce bez návratové hodnoty, předává se jí při volání hodnota
    {
        for (int i=0; i<n; i++)
            cout << "Ahoj \n";
        cout << "konec";
    }

Parametr int n v seznamu znamená, že f-ce pozdrav() očekává při jejím volání hodnotu typu int (proměnná n zde není důležitá).

Funkce s návratovou hodnotou vyžadují použití příkazu return, který se stará o navrácení hodnoty volající f-ci:


    jmeno_typu jmeno_funkce(seznam_parametru)
    {
        příkazy
        return hodnota;        // hodnota má stejný typ, jako jméno_typu
    }

Hodnotou myslíme proměnnou, konstantu či obecněji výraz. Hodnota se vždy reprodukuje na jmeno_typu nebo se na něj konvertuje (je-li definován typ double a navrácená hodnoty je typu int (např. 8), tak se konvertuje int na double (8.0)), návratová hodnota nemůže být pole. Vše ostatní je možné. F-ce se ukončí, jakmile narazí na příkaz return. F-ce ale může mít i více než jeden příkaz return – např. jako alternativy k různým volbám:


    int porovnani(int a, int b)
    {
        if (a > b)
            return a;        // jel-li a>b, funkce se ukončí zde a navrátí hodnotu a
        else
            return b;        // jinak se f-ce ukončí zde a navrátí se hodnota b
    }

Else zde není třeba, ale pomůže lépe pochopit závěr. Následující příklad nám vrací druhou mocninu čísla:


    double ctverec(double x)
    {
        return x * x;    // hodnota typu double
    }

Jestliže tedy při volání f-ce předáme hodnotu 2, navrátí nám f-ce hodnotu 4.

Vytváření prototypů

Prototyp vytvoříme velmi lehce (nezabývejte se teď tím, kam jednotlivé části f-ce patří). Stačí zkopírovat první řádek definici f-ce a dát za něj středník. Pokud tedy použijeme v programu naše napsané f-ce porovnani a ctverec, jejich prototyp bude vypadat takto:


    int porovnani(int a, int b);
    double ctverec(double x);

Prototyp popisuje rozhraní f-ce ke kompilátoru, říká mu, jakého typu je návratová hodnota, počet a typ parametrů f-ce. Stále jste možná zvědaví, proč prototyp f-ce kompilátor potřebuje. Kompilátor se díky prototypům seznámí se všemi f-cemi použitými v programu, aniž by je musel „hledat“. Neboli čtení kódu probíhá shora dolů a museli byste bez použití prototypu f-ci definovat před jejím prvním použitím. To není efektivní, protože hlavní f-cí je main. Prototyp tedy oznamuje přítomnost dalších f-cí a odkáže kompilátor na její umístnění. Prototyp f-ce nevyžaduje jména proměnných – seznam typů postačuje.


void pozdrav(int);        // vypustit jména proměnných je v prototypech v pořádku

Automatická konverze ovšem nemusí vždy konvertovat hodnotu správně, a to v případě z většího na menší. Například předáváte-li hodnotu 8.54E26 f-ci, která čeká int, nemusí se konvertovat tak velké číslo správně. V tomto případě vás kompilátor varuje před možnou ztrátou dat.

Volání funkce

Pokud chceme zavolat f-ci, není nic lehčího, než napsat její jméno a popřípadě jí předat parametry:


    jméno_funkce(seznam_parametrů);

…takže například:


    ctverec(5);

Tímto voláním zavoláme f-ci ctverec a předáme jí parametr, v tomto případě číslo 5. Když se podíváme nahoru (jak jsme definovali f-ci ctverec), tak zjistíme, že nám má vrátit hodnotu na druhou, tedy 25:


cout << ctverec(5);

…zobrazí hodnotu 25. A stejně můžeme zobrazit proměnné, které se inicializují až za běhu programu:


    int a;
    cin >> a;            //dejme tomu, že jsme zadali hodnotu 6
    cout << ctverec(a);        //zobrazí 36

Nyní si ukážeme příklad:


#include <iostream>
using namespace std;
void pozdrav(int);                 // prototyp: žádná návratová hodnota
double kostka(double x);      // prototyp: vrací hodnotu typu double
int main()
    { 
        pozdrav(5); // volání funkce => předá 5ku f-ci pozdrav
        cout << "Zadejte cislo: ";
        double strana;
        cin >> strana;
        double prom = kostka(strana); // volání funkce a přiřazení hodnoty do proměnné prom
        cout << "Krychle o velikosti strany " << strana <<" metru ma objem ";
        cout << prom << " metru krychlovych.\n";
        pozdrav(kostka(2));                 // ukázka prototypové ochrany
        return 0;
    } 

void pozdrav(int n)
    { 
        for (int i = 0; i < n; i++)
        cout << "Slava! ";
        cout << "\n";
    } 

double kostka(double x)
    { 
        return x * x * x;
    } 

Co se týče prototypové ochrany, není to nic víc, než použití f-ce ve f-ci.

Parametry funkcí a předávání hodnotou

C++ předává obvykle parametry hodnotou. To znamená, že se číselná hodnota parametru předá f-ci, která se přiřadí do nové proměnné.


    double prom = kostka(strana);

…a její hlavička funkce byla:


    double kostka(double x)

Když se tato f-ce vyvolá, vytváří novou proměnnou typu double, která se nazývá x a přiřadí jí hodnotu 5. Dále jako parametr můžete použít proměnnou stejného jména, jako máte již někde použité. Tedy pokud máte např.:


    ..
    int main()
    {
        int lek=15;
        ..    
    }

    double druha (int lek)
    ...

…tak tyto dvě proměnné jsou úplně rozdílnými proměnnými (lek), poněvadž druhá lek existuje jen uvnitř těla f-ce, tudíž se na ní nemůžete nějak dovolávat a nelze si ji tedy splést s první proměnnou lek. Je to podobné, jako se liší Albana v Kalifornii a Albana v New Yorku.

Násobné parametry

Funkce mohou mít víc než jeden parametr. Ve volání f-ce pouze oddělte parametry čárkou:


    kostka('R', 25);

To předává f-ci, kterou si za chvíli definujeme, dva parametry. Když ji deklarujete, postupujte stejně:


    void kostka(char c, int n)        // 2 parametry

POZOR, pokud definujeme dva parametry stejného typu, nemůžeme je vytvářet jako klasické proměnné:


    int a,b;        //klasické proměnné
    void(int a, b)    // nelze
    void(int a, int b)    // takto je to správně

Stejně tak postupujeme i u vytváření prototypu:


    void(int a, int b);

Tak to by bylo všechno. Knihovnu cctype si necháme na později. Možná vyjde jako dodatek (jelikož jsem zjitil, že jsou dodatky důležité, tak jsou nyní již pojmenované jako normální lekce). V příští lekci (pokud to nebude ta knihovna) se budeme zabývat… funkcemi… nečekaně ;) Protože f-ce jsou velké téma! Ještě si musíme ukázat, jak pracují s řetězci a poli. A co nás čeká potom? Dvourozměrná pole, ukazatele, ukazatele na struktury, pole…

Úkol:

Vytvořte program, který bude v int main() obsahovat:

int a;
cout << "zadejte číslo: ";
cin >> a;

…a nyní bude následovat menu (počet položek nechám na vás), kde vám ukáže výsledky operací s tímto číslem. Tedy uděláte několik f-cí a každá z nich bude počítat jednu operaci.

Příklad:

zadejte číslo: 5
číslo na druhou je: 25
číslo je: jednociferné

…a podobně. Prostě toto vám ukázalo dvě operace (dvě položky) a vy se snažte udělat menu s co nejvíce položkami, co vás napadne udělat s číslem. Každá položka bude ale počítaná ve vlastní f-ci, tedy ne přímo v int main! int main může obsahovat pouze kód uveden výše a jen volání f-cí.


Článek stažen z webu Programujte.com [ http://programujte.com/clanek/2005041410-c-6-lekce/ ].