Pointery

Pointery (neboli ukazatele) slouží pro práci s adresou paměti, na které se nachází hodnota proměnné.

Představme si, že máme proměnnou i, která bude mít hodnotu 20. Deklaraci a inicializaci proměnné můžeme udělat v jednom příkazu:

int i = 20;

V momentě, kdy vytvoříme novou proměnnou, alokuje se oblast paměti (v tomto případě velikosti 4 B, protože datový typ proměnné je int) a na tom místě se bude ukládat hodnota proměnné.

S pointery jsme se v programování setkali při načítání proměnných. Funkce jako scanf() totiž vyžaduje zadat adresu, kam se bude hodnota ukládat:

scanf("%d", &x);

Stejně tak si můžeme vypsat adresu proměnné, například

int i = 20;
printf("Na adrese %p je uložena hodnota %d.\n", &i, i);

Pointery používáme jako odkazy na místo v paměti, kde je uložena hodnota proměnné, především při

Deklarace pointeru

Pointer je vlastně pouze adresa prvního bytu, na které je uložena proměnná.

Deklarujeme jej pomocí typu proměnné, na kterou ukazuje v kombinaci se znakem *:

int *pa;   //pointer na int
char *pc;  //pointer na char 
float *pf; //pointer na float

Touto deklarací jsme si pouze vytvořili pointer (ukazatel), ale ten zatím nikam neukazuje. Abychom nastavili adresu, kam bude pointer ukazovat, je potřeba provést jeho inicializaci.

Inicializace pointeru

Poté, co máme pointer deklarován, musíme říci, na jakou proměnnou bude pointer ukazovat.

Mějme například

int x = 12;
int *pint;

Abychom do pointeru pint uložili adresu proměnné x, musíme provést příkaz:

pint = &x;

Nyní v proměnné pint máme uloženou adresu, na které můžeme najít hodnotu proměnné x.

Operátory

Při práci s pointery (ukazateli) budeme tedy používat dva operátory:

Máme-li příklad zobrazený výše, tak na hodnotu x se můžeme dostat také pomocí operátoru hvězdička:

printf("Na adrese %p je uložena hodnota %d.\n", pint, *pint);

Naopak do proměnné pint můžeme uložit adresu jiné proměnné pomocí operátoru ampersand:

int y = 25;
pint = &y;

Generovaný podcast o ukazatelích (pointerech) si můžete poslechnout zde:

Podcast byl automaticky vygenerován z této stránky a z webu https://www.geeksforgeeks.org/c/c-pointers/

Dynamické alokování velikosti pole

Když jsme začínali pracovat s polem, deklarovali jsme jej vždy pomocí pevně stanovené velikosti, například:

int znamky[5];

V tomto případě nám kompilátor alokuje 5 × 4 B paměti (za předpokladu, že pro jedno celé číslo potřebujeme 4 B). Proměnná znamky v tom případě bude vlastně pointer, který ukazuje na první prvek v daném poli.

Někdy ale dopředu nevíme, kolik prvků budeme do pole chtít uložit. Strategie použít místo čísla 5 v příkladě výše opravdu velké číslo naráží na optimální využití paměti, čili tudy cesta také nevede.

Představme si, že počet prvků pole víme až na základě nějaké proměnné, jejíž hodnotu získáme v průběhu daného programu:

//deklarace pocetZnamek už proběhla

pocetZnamek = 69;
int *znamky;

znamky = (int *) malloc(pocetZnamek * 4);

//nyní můžeme do pole znamky naplnit až 69 prvků

K dynamickému alokování paměti jsme použili funkci malloc() – zkratku z anglického memory allocation – jejímž parametrem je počet bajtů, které chceme přiřadit (v tomto případě pocetZnamek × 4, protože jeden int zabírá 4 B).

Příklady s pointery

Příklady s pointery si můžete zobrazit zde.

Příklady s pointery na webu w3resource si můžete zobrazit zde.