přejít na obsah přejít na navigaci

Linux E X P R E S, Programovanie v jazyku C++: Pointery ukazujúce na funkcie

Programovanie v jazyku C++: Pointery ukazujúce na funkcie

cplusplus.png

Vedeli ste, že pointery môžu ukazovať nielen na rôzne typy premenných, ale aj na funkcie? Ukážeme si, ako vytvoriť pointer, ktorý ukazuje na zvolenú funkciu.


Definujeme pointery ukazujúce na funkcie

Už vieme, že pointer je premenná, ktorá uchováva adresu inej premennej. Pointer môže ukazovať nielen na umiestnenie inej premennej, ale aj na umiestnenie samotnej funkcie! Aby sme si to ukázali, na začiatok si implementujeme jednoduchý program. Tento program nám bude slúžiť ako odrazový mostík vo vysvetľovaní.

#include <iostream>

#include <ctime>

#include <cstdlib>

using namespace std;

 

void vypis(int nahodneCislo)

{

    cout << "Z intervalu 1-100 bolo vylosovane cislo: " << nahodneCislo << "\n";

}

 

int main()

{

    srand(time(0));

    int nahodneCislo = rand() % 100 + 1;

    vypis(nahodneCislo);

    return 0;

}

Výsledok programu:

Z intervalu 1-100 bolo vylosovane cislo: 33

Vytvorili sme jednoduchý program, ktorý vylosuje náhodne číslo v intervale od 1 do 100. Nič komplikované. Skúsme však definovať pointer, ktorý bude ukazovať na funkciu vypis().

#include <iostream>

using namespace std;

 

void vypis()

{

    cout << "Ahoj mily pouzivatel. Som ti uplne k dispozicii :)";

}

 

int main()

{

    void (*pointerVypis)() = vypis;

    pointerVypis();

    return 0;

}

Výsledok programu:

Ahoj mily pouzivatel. Som ti uplne k dispozicii :)

Takže čo sa zmenilo? Museli sme pridať jeden riadok kódu, aby sme definovali pointer, ktorý bude ukazovať na našu definovanú funkciu vypis(). Celé znenie aj už s priradením adresy funkcie do prázdneho pointeru vyzerá takto: void (*pointerVypis)() = vypis;. Do zátvorky sme dali deklaračný znak pointeru * a meno pointeru. Pravidla priradenia adresy funkcie pre pointer je rovnaká ako u premenných.

Teraz sa vráťme k prvému príkladu a upravme ho tak, aby pointer ukazoval na funkciu s jedným parametrom.

#include <iostream>

#include <ctime>

#include <cstdlib>

using namespace std;

 

void vypis(int nahodneCislo)

{

    cout << "Z intervalu 1-100 bolo vylosovane cislo: " << nahodneCislo << "\n";

}

 

int main()

{

    srand(time(0));

    int nahodneCislo = rand() % 100 + 1;

    void (*los)(int) = vypis;

    los(nahodneCislo);

    return 0;

}

Výsledok je samozrejme rovnaký, len vylosovaná hodnota je iná. Všimnite si, že sme pridali do zátvorky int, viď. void (*los)(int) = vypis;.

Teraz skúsme zmeniť funkciu vypis() tak, aby vracala návratovú hodnotu typu int. Uspôsobíme aj tvorbu pointeru tak, aby ukazoval na funkciu s návratovou hodnotou int.

#include <ctime>

#include <cstdlib>

using namespace std;

 

int vypis(int nahodneCislo)

{

    nahodneCislo = rand() % 100 + 1;

    return nahodneCislo;

}

 

int main()

{

    srand(time(0));

    int nahodneCislo = 0;

    int (*los)(int) = vypis;

    nahodneCislo = los(nahodneCislo);

    cout << "Z intervalu 1-100 bolo vylosovane cislo: " << nahodneCislo << "\n";

    return 0;

}

Oproti predchádzajúcemu príkladu, sme upravili tvorbu pointeru aj zmenili funkciu výpis() tak, aby vrátila celočíselné hodnoty, čiže typu int.

Zvládli sme základy tvorby pointerov, ktoré odkazujú na funkcie. Zatiaľ to však vyzerá, že je to viacmenej zbytočné. Predsa, všetky uvedené príklady sa dajú použiť aj bez pointerov na funkcie a dokonca ušetríme minimálne jeden riadok kódu. Skúsme sa ale pozrieť na príklad, v ktorom potencionálne pointer ukazujúci na funkciu môže byť užitočný.

#include <iostream>

#include <ctime>

#include <cstdlib>

using namespace std;

 

void chybovaHlaska()

{

    cout << "Nulou sa nedeli! Program predcasne konci!\n";

    exit(0);

}

 

int scitanie(int nahodneCislo1, int nahodneCislo2)

{

    int vysledok = nahodneCislo1 + nahodneCislo2;

    return vysledok;

}

 

int odcitanie(int nahodneCislo1, int nahodneCislo2)

{

    int vysledok = nahodneCislo1 - nahodneCislo2;

    return vysledok;

}

 

int nasobenie(int nahodneCislo1, int nahodneCislo2)

{

    int vysledok = nahodneCislo1 * nahodneCislo2;

    return vysledok;

}

 

int delenie(int nahodneCislo1, int nahodneCislo2)

{

    int vysledok = 0;

    if(nahodneCislo2 != 0)

        vysledok = nahodneCislo1 / nahodneCislo2;

    else chybovaHlaska();

    return vysledok;

}

 

int main()

{

    srand(time(0));

    int nahodneCislo1 = rand() % 100;

    int nahodneCislo2 = rand() % 100;

    int volba = 0;

    int (*mat_operation)(int,int);

    cout << "Zvol operaciu:\n" << "1 - scitanie\n" << "2 - odcitanie\n" << "3 - nasobenie\n" << "4 - delenie\n";

    cout << "Tvoja volba je: ";

    cin >> volba;

    if(volba == 1)

        mat_operation = scitanie;

    else if (volba == 2)

        mat_operation = odcitanie;

    else if (volba == 3)

        mat_operation = nasobenie;

    else if (volba == 4)

        mat_operation = delenie;

    else

    {

        cout << "Neplatna volba, program konci!\n";

        return 0;

    }

 

    cout << "Vysledok vasej zvolenej operacie medzi dvoma nahodnymi cislami "<<nahodneCislo1<< " a "<<nahodneCislo2 << " je: " << mat_operation(nahodneCislo1, nahodneCislo2) << "\n";

    return 0;

}

Výsledkom programu je:

Zvol operaciu:

1 - scitanie

2 - odcitanie

3 - nasobenie

4 - delenie

Tvoja volba je: 2

Vysledok vasej zvolenej operacie medzi dvoma nahodnymi cislami 69 a 46 je: 23

Princípom programu je, že užívateľ si vyberie, aká matematická operácia sa vykoná nad dvoma číslami. Po vybratí matematickej operácie sa priradí pointeru tá funkcia, ktorú vybral používateľ. Čiže ak vybral sčítanie, tak vyberie funkciu scitanie(). Takáto implementácia ukazuje smer, ako môžete využiť pointery ukazujúce na funkcie.

Námet na tento článok poslúžili tieto zdroje:

7.8 — Function Pointers, learncpp.com, dostupné online

Function Pointer in C, geeksforgeeks.org, dostupné online

Nahoru

Příspěvky

Programovanie v jazyku C++: Pointery ukazujúce na funkcie
D.A.Tiger 22. 06. 2019, 23:02:37
Odpovědět  Odkaz 
Zdravim,
Nebylo by mozna lepsi na menu vyuzit prepinac, nez pomerne komplikovanou serii podminek?
Eduard Boldižár Re: Programovanie v jazyku C++: Pointery ukazujúce na funkcie
Eduard Boldižár 23. 06. 2019, 00:08:54
Odpovědět  Odkaz 
Z hľadiska funkcionality medzi if-else podmienkami a prepínačmi nie je rozdiel. Ale uznávam, že esteticky to nie je bohviečo :) zvážim to to budúcností, vďaka za tip ;)
Programovanie v jazyku C++: Pointery ukazujúce na funkcie
fela 23. 06. 2019, 17:17:00
Odpovědět  Odkaz 
Ďakujem za ďalšiu časť seriálu, už som sa obával, že to pomaly umiera...
Programovanie v jazyku C++: Pointery ukazujúce na funkcie
Noro 25. 06. 2019, 09:02:06
Odpovědět  Odkaz 
neviem kde robim chybu, ale uz hned prvy priklad napisal nieco taketo
~/tmp:gcc pokus.cc
/usr/bin/ld: /tmp/ccyZvW6h.o: in function `vypis(int)':
pokus.cc:(.text+0x15): undefined reference to `std::cout'
/usr/bin/ld: pokus.cc:(.text+0x1a): undefined reference to `std::basic_ostream& std::operator
Programovanie v jazyku C++: Pointery ukazujúce na funkcie
Noro 25. 06. 2019, 09:08:58
Odpovědět  Odkaz 
nejako to nezobrazilo cely vypis
https://imgur.com/a/G7QbDEJ
~/tmp:gcc --version
gcc (GCC) 9.1.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Eduard Boldižár Re: Programovanie v jazyku C++: Pointery ukazujúce na funkcie
Eduard Boldižár 25. 06. 2019, 11:57:23
Odpovědět  Odkaz 
Vidím tam gcc. Programy C++ sa kompilujú cez g++. Ale dá sa aj cez gcc, ale treba tam niečo pridať. Celý gcc príkaz má vyzerať takto: gcc program.cpp -lstdc++ -o program.o
Môžte sa pozrieť i tu, ak by nebolo niečo jasné: stackoverflow.com/questions/28236870/undefined-reference-to-stdcout
Programovanie v jazyku C++: Pointery ukazujúce na funkcie
Noro 25. 06. 2019, 19:42:43
Odpovědět  Odkaz 
Dakaujem uz to islo skompilovat aj cez g++ aj gcc

Přidat názor

Nejsou podporovány žádné značky, komentáře jsou jen čistě textové. Více o diskuzích a pravidlech najdete v nápovědě.
Diskuzi můžete sledovat pomocí RSS kanálu rss



 
 

Top články z OpenOffice.cz