Ukazatele

Ukazatel, neboli pointer je proměnná se zvláštním významem. Neukládá běžné hodnoty, na které jsme zvyklí z jednoduchých datových typů, ale ukládá adresu jiné proměnné, datové struktury, nebo funkce.

Deklarace a datový typ ukazatele

Ukazatel je vždy svázán s určitým datovým typem. Není to jen "ukazatel", ale je to "ukazatel na", proto když deklarujeme ukazatel, uvádíme i datový typ proměnné, na kterou ukazuje. Proměnnou, která je ukazatelem, definujeme pomocí hvězdičky před jejím názvem.

dat_typ *identifikator;

Příklad: Deklarace ukazatele

int a; // Deklarace proměnné a
int *p1; // Deklarace ukazatele p1
// Stejně jako u jiných proměnných, není hodnota p1 definována

Operátory pro práci s ukazateli

Aby jsme mohli ukazatel prakticky využít, musíme do něj nejdříve uložit adresu na proměnnou určitého typu. Zároveň je přirozeně potřeba pracovat s hodnotou, která je uložena na místě, kam ukazatel fakticky ukazuje. K tomu slouží unární operátory reference (&) a dereference (*)

&Reference - adresaZíská adresu proměnné uvedené jako pravý operand
*Dereference - hodnotaPracuje s hodnotou na kterou ukazuje ukazatel

Příklad: Inicializace a přiřazení hodnot

int a;
int *p1 = &a; // Přiřazení adresy proměnné "a" do ukazatele p1
*p1 = 10; // Přiřazení hodnoty 10 do proměnné "a" skrze ukazatel

Aritmetické a logické operace s operátory

S ukazateli můžeme podobně jako s ostatními proměnnými provádět určité operace. Tyto operace jsou ale značně omezené a mají svůj specifický význam. Jejich využití je nejobvyklejší pri práci se sekvenčními daty, jako jsou obecná pole a řetězce.

Rozdíl ukazatelů stejného typu:Získáme vzdálenost dvou ukazatelů v počtu položek typu, na který ukazatel ukazuje. Když si paměť představíme jako pole stejného typu, tak rozdíl ukazatelů je jako odečtení dvou indexů tohoto pole.
Přičtení/odečtení celého čísla od ukazatele:Celé číslo v tomto případě představuje počet položek, o které se ukazatel v paměti posune. Opět si můžeme ukazatel představit jako index do pole, a přičtení čísla jako sčítání dvou indexů.
Porovnání dvou ukazatelů stejného typu:Ukazatele stejného typu lze mezi sebou porovnávat pomocí relačních operátorů.

Příklad: Vynulování pole

int arr[10];
int *polozka = arr; // arr odpovídá ukazateli na začátek pole
int *konec = polozka + 10; // konec ukazuje na položku za koncem pole (arr[10])

while (polozka < konec) { // Porovnání dvou ukazatelů
    *polozka = 0; // Nastavení hodnoty položky na 0
    polozka++; // Posun ukazatele o jednu položku
}

Null ukazatel

Null, nebo nil je speciální hodnota ukazatele, která znamená, že ukazatel neukazuje nikam. V jazyce C a C++ je to standardně ukazatel s hodnotou 0, nebo lze použít konstantu NULL definovanou např. v hlavičkovém souboru stdlib.h/cstdlib. Pokud zkusíme dereferencovat ukazatel s hodnotou NULL, dojde k běhové chybě známé jako "chyba segmentace".

Ukazatel typu void

Můžeme vytvořit ukazatel typu void, o takovém ukazateli říkáme, že je nespecifikovaného typu a velikosti. Hodí se jako univerzální ukazatel. V případě pokusu o dereferenci takového ukazatele nastane chyba. Abychom mohli využít hodnotu odkazovanou ukazatelem typu void, musíme tento ukazatel nejdříve přetypovat.