Hledejte v chronologicky řazené databázi studijních materiálů (starší / novější příspěvky).

23. Ukazatele na struktury, ukazatele na funkce.

Ukazatel na struktury:
Na struktury lze ukazovat stejně jako na jakýkoliv typ proměnné.

název_struktury *identifikátor;

Příklad:

struct DATUM{
int den;
int mesic;
int rok;
};

struct CD{
char nazev[31];
int cislo;
DATUM vydano;
};

void main()
{
CD *test = new CD; //deklarace ukazatele test
printf(“%d“,test->cislo); /*Vypíše obsah proměnné cislo ze struktury na
kterou ukazuje test.*/
printf("%d",(*test).cislo); //Udělá totéž
printf(“%d“,(*test).vydano.den); /*Vypíše obsah proměnné den ve struktuře DATUM, kterou obsahuje struktura CD.*/
}

Z předcházejícího příkladu je viděť, že lze vytvářet libovolně vnořené struktury a přistupovat k nim pomocí pointerů.

Největší pointerů je, pokud chceme vytvořit dynamickou databázi struktur. Pak by struktura CD ještě obsahovala ukazatel sama na sebe, které bychom vždy přiřadily adresu následující struktury CD. Příklad viz maturita z Cčka :)

Ukazatele na funkce:
Kromě klasických datových ukazatelů, s kterými jsme se doposud setkávali, nabízí jazyk C(C++) i ukazatele kódové. Ty ukazují na určitý úsek kódu (funkci) programu, který pak můžeme spustit nepřímo, právě pomocí těchto ukazatelů.

Definice ukazatele na funkci
Uvažujme, že máme nadefinovanou tuto funkci pro sčítání čísel double:

double secti(double a, double b)
{ return a+b;
}

Tuto funkci můžeme volat normálně, jak jsme zvyklí, nebo si můžeme vytvořit ukazatel na ni a volat ji pomocí něho. Formální zápis definice takového pointeru vypadá takto:

typ (*identifikátor)(seznam_typů_parametrů)

Typem rozumíme datový typ, který vrací funkce, na kterou bude ukazovat náš pointer. Identifikátor je pak označením tohoto nového pointeru a v seznamu_typů_parametrů jsou, v odpovídajícím pořadí, uvedeny všechny typy parametrů odkazované funkce. Tento seznam sice můžeme nechat prázdný, ale kompilátor by v tomto případě neměl informace o typech parametrů funkce. Pokud bychom pak volali funkci, nepřímo přes ukazatel, se špatnými typy parametrů, mohlo by to vést ke špatné funkci programu.

Příklad na funkci secti():

double (*pf)(double, double);

Pointer pf teď může ukazovat na jakoukoliv funkci, která má dva parametry typu double a hodnotu typu double i vrací, tedy může ukazovat i na naši funkci secti(). Tento ukazatel je ale zatím neinicializovaný a pro volání funkce ho ještě nemůžeme použít. Jeho inicializaci provedeme prostým přiřazením identifikátoru existující funkce.

Inicializace kódového ukazatele

pf=secti;

Do proměnné pf byl uložen ukazatel na funkci secti(). Identifikátor přiřazované funkce se musí uvádět bez závorek se seznamem parametrů a nemusíme(ale můžeme) použít operátor & pro získání adresy. Kompilátor dokáže rozeznat, že chceme přiřadit ukazatel na funkci a ne funkci samotnou.

pf=§secti;

Ukazatel na funkci se dá inicializovat i jinými způsoby, podobně jako datový ukazatel. Můžeme tedy přiřazovat vzájemně kompatibilní ukazatele, inicializovat návratovou hodnotou funkce apod.

Volání funkce pomocí ukazatele
Jak už jsme si řekli, lze k volání funkce použít i ukazatele na tuto funkci. Zápis takového volání se řídí podle jednoho z následujících zápisů:

(*identifikátor_ukazatele)(seznam_skutečných parametrů);

nebo

identifikátor_ukazatele(seznam_skutečných parametrů);

Oba zápisy jsou funkčně ekvivalentní, a protože druhý z nich je jednodušší a bližší skutečnému zápisu volání funkce, budeme ho nadále používat.
Výše nadefinovaný a inicializovaný pointer pf bychom tedy pro zavolání jím odkazované funkce použili následujícím způsobem.

pf(15,4);

Výsledkem po vyhodnocení tohoto výrazu bude double hodnota 19.0, stejně jako kdybychom zavolali funkci

secti(15,4);

na kterou pointer pf ukazuje.

Kódový ukazatel jako parametr funkce a její návratová hodnota
I kódový ukazatel můžeme bez problémů předat funkci jako její parametr, a to stejně, jako bychom to udělali s proměnnou jiného typu.

Žádné komentáře:

Okomentovat