Ukazatele v C++
Proměnná vs Ukazatel
Proměnná je prostor v paměti, který ke kterému můžeme přistoupit podle jeho jména, jména proměnné. Ukazatel naopak odkazuje na přesné místo v paměti, kde se takováto proměnná nachází a umožňuje nám ji upravovat přímo v paměti.
Proměnná dokáže uchovávat hodnotu, která je uložena na své adrese v paměti.
Ukazatel uchovává přesnou adresu místa, kde se proměnná nebo místo pro ni vytvořené nachází.
Deklarace, inicializace a přístup k obsahu ukazatele
Při deklaraci musíme jako první určit datový typ ukazatele aby program věděl na jaký datový typ ukazatel vlastně ukazuje (ukazatelé nemají datový typ, ale data na které ukazují ano a proto se musí datový typ deklarovat). Dále napíšeme hvězdičku a jméno ukazatele .
int * number;
char * character;
double * decimal;
Ukazatel uchovává adresu paměti, takže ho můžeme inicializovat adresou již vytvořené proměnné nebo můžeme místo v paměti pro proměnnou vytvořit sami. Adresu proměnné získáme tak, že před název proměnné napíšeme ampersand(&). Pokud chceme vytvořit prostor pro proměnnou sami, použijeme slovo new a datový typ, který chceme v paměti uchovávat a tím se nám v paměti vytvoří dostatečně velký prostor pro daný datový typ. Dále může být ukazatel inicializován jiným, již inicializovaným ukazatelem.
| Hodnota | Adresa | |
|---|---|---|
| Proměnná | nazevX | &nazevX |
| Ukazatel | *nazevY | nazevY |
pointer = new type
pointer = new type [pocet_prvku]
int cislo =
10;
int * ukazatel;
ukazatel1 = &cislo;
int * foo;
ukazatel1 = new int [5];
Pokud chceme nastavit hodnotu proměnné, na kterou ukazatel ukazuje, musíme před jméno ukazatele napsat hvězdičku a tak se dostaneme přímo k hodnotě, která se nachází na adrese, kterou ukazatel uchovává.
*ukazatel = 10;
New, delete, dynamická alokace paměti
Slovo new vytvoří prostor v paměti, který se rovná velikosti datového typu, na který ukazatel ukazuje. Pokud chceme vytvořit prostor v paměti pro pole daného datového typu, tak při inicializaci ukazatele napíšeme za new a datový typ, hranaté závorky a určíme pro kolik prvků pole se má alokovat paměť. Takto dynamicky alokované místo v paměti se zde bude nacházet až do té doby, než jej smažeme.
Slovo delete smaže námi vytvořený prostor v paměti a jeho obsah. Pokud jsme v paměti udělali prostor pro pole prvků musíme za delete napsat hranaté závorky(delete[]) a tak smažeme celé pole. Pokud tak neuděláme, dojde ke smazání pouze prvního prvku tohoto pole.
delete ukazatel;
delete[] ukazatel_pole;
Adresa pole
Pokud deklarujeme pole vytvoříme tak i adresu na první prvek pole. Samotné pole je adresou, která odkazuje na první prvek pole. Název pole v sobě uchovává tedy adresu na první prvek pole, pokud před název pole napíšeme ampersand(&) dostaneme stejnou adresu. Jediný rozdíl je, že pokud přidáme hodnotu k adrese získanou z ampersandu(&) program přeskočí celou paměť ve které se nachází pole, zatím co u adresy získané jenom z adresy názvu pole se posuna na druhý prvek pole.
int pole[5] =
{ 5, 65,
98, 47,
52
};
cout << pole << endl;
cout << &pole << endl;
// vypíše se stejná adresa
Aritmetika ukazatelů
K adresám, které ukazatele uchovávají můžeme přičítat nebo odečítat hodnoty a posouvat tak paměť, na kterou ukazatel ukazuje. Takovéto operace jde využít například při dynamické alokaci paměti pole, kde adresa na pole odkazuje na první prvek pole, pokud tedy přičteme 1 dostaneme se na adresu paměti druhého prvku pole.
Přičtení 1 k adrese ukazatele posune ukazatel o počet bitů daného datového typu (každý datový type je jinak veliký, má jiný počet bitů, které zabírá v paměti)

Ukazatele a práce s textovými řetězci
Ukazatele lze využít při vytváření dynamického pole charů. Od uživatele získáme string a zjistíme jeho velikost, ke které přičteme 1, kvůli tomu, že string v sobě obsahuje nulový charakter(charakter, který ukončuje textový řetězec), který se však nepočítá do délky stringu. Musíme ho tedy přičíst ručně. Poté inicializujeme ukazatel pole charů s velikostí stringu+1. Dále využijeme funkci strcpy(), abychom zkopírovali hodnotu stringu do vytvořené paměti ukazatele. K stringu připojíme funkci c_str(), která vrací ukazatel na pole charů už i s nulovým charakterem. Funkce strcpy() tedy zkopíruje toho pole do adresy ukazatele.
string slovo =
"Ahoj";
int pocet_charu = name.length() + 1;
char * kopie_slova =
new char[pocet_charu];
strcpy(kopie_slova, slovo.c_str());
Ukazatele a práce se strukturou
Pokud chceme vytvořit ukazatel na strukturu, můžeme to udělat tak, že mezi typ a název struktury připíšeme hvězdičku. S takovýmto ukazatelem se pak pracuje uplně stejně jako se všemi ostatními ukazateli. Jediné co se změní je práce se strukturou. Konkrétně přístup k proměnným uložených ve struktuře. Nebudeme k nim přistupovat pomocí “.“, ale pomocí ->.
Pole jako parametr funkce
Do funkce lze přidat pole jako její parametr. Lze to udělat několika způsoby. Prvním je, že do parametrů funkce přidáme pole (int cisla[]). Druhý způsobem to uděláme tak, že do parametrů funkce budeme posílat ukazatel na pole. Kompilátor oba tyto způsoby jako identické, protože v obou případech se do funkce posílá ukazatel na první prvek pole (pole int cisla[] uchovává adresu na první prvek pole, pokud do pole pošleme adresu pole, také ukazuje na první prvek pole). Takže posílání pole do funkce je vlastně jen ulehčení pro člověka. Kompilátor v obou zápisech vidí ukazatel na pole. Proto ve funkci, do které jsme poslali pole jako parametr, nemůžeme ziistit velikost pole, protože se jedná pouze o ukazatel na pole a ne o pole jako takové.
Ukazatel na funkci
V C++ můžeme vytvořit ukazatel i na funkci. Nejčastěji se používá při posílání funkce jako parametr jiné funkce. Ukazatel na funkci se vytváří také pomocí * s tím rozdílem, že název funkce s * je uzavřen v závorkách.
int add(int
a, int b)
{ return a + b; }
int
subtract(int
a, int b)
{ return a - b; }
int
operace(int x,
int y,
int (*funkce) (int, int))
{ return (*funkce) (x, y); }
int main()
{
int soucet =
operace(5,
7, add);
int rozdil =
operace(5,
7, subtract);
}
Videa
Kvíz
BETACo je to ukazatel (pointer) v C++?
Ukazatel (pointer) v jazyce C/C++ je speciální proměnná. Na rozdíl od klasických proměnných neuchovává aktuální datovou hodnotu (např. číslo 10), nýbrž slouží jako směrovací logická cedulka – je to prostá hexadecimální adresa ukazující do operační paměti RAM na místo, kde příslušná data aktuálně sídlí.
Jaký operátor vrátí adresu proměnné v C++?
Prefixní operátor ampersand (znak `&`) plní v C++ roli referenční mapy u adres paměti. Zápisem operátoru před proměnnou, například napojením z příkazu `&pocet`, nezjistíte obsah čísla v proměnné počtu, avšak neomylně lokalizujete její skryté šestnáctkové hardwarové umístění v paměťovém sektoru (např. 0x0A).
Jaký operátor dereferencuje ukazatel (přistoupí k hodnotě) v C++?
Zatímco s prázdnou adresní hodnotou (např. 0x0A2B) se operuje v logické paměti a bez dat, skrze operátor obyčejné prefixové hvězdičky provedete takzvanou dereferenci. Příkazem typu `*ukazatel` donutíte program navštívit schovanou paměťovou dálku adresy a vytáhnout anebo upravit přímo samotný její stíněný a hlídaný vnitřní zapsaný číselný i znakový obsah.
Co dělá operátor `new` v C++?
Příkazově volaný operátor `new` vysílá během chodu běhu na softwaru pécéček systémový rozkaz o okamžité uvolněné datové přídavky. Přiděluje rozšiřitelnou paměť pro variabilní data uvnitř dlouhodobější svobodné tzv. haldy (Heap). A místo dat do zdrojů vaší C++ operace hned pošle jako potvrzení pouze čitý ukazatel na přidělenou zónu RAM pamětí.
Co dělá operátor `delete` v C++?
U C/C++ absence vnitřního automatizovaného chytrého drtiče a úklidáře objektů a smetí napřímo vyžaduje nesmírnou zodpovědnost a uvolňování v logice zdrojů na ruční bázi manuálně. Pokud tak před datovou smrtí a ukočením softwérového i objektového zniku nezrušíte napojený paměťový most vytvoření k heapu (halda z opráce od povele z new) přes destruktivní příkaz slovům `delete`, navždy utratíte nevrácením dat u ram cely prostor operačnich limitů počítače systémem (tzn Memory Leak poruchou).
Co je to dangling pointer?
Dangling pointer (takzvaný visící ukazatel) označuje utržené obávané poškozené torzo pro pointer. Zástupce už veškerým svým vlivem dál odkazuje nesmyslnou chybou ukazatele přímo ke zcela zakázané konkrétní i uvolněné fyzicke adrese (kterou dřív dříve systém už nebezpečně a legálně zahladil i vypustil příkazem delete). Pokus z takové datové zrušené pasti RAM cokoly ještě tahat znamená obratem závažné i nevratně kritické sebedestruktivní spadnutí celé bezesporu kódové softwarovém struktuoře.
Jak se přistupuje k členu struktury přes ukazatel v C++?
U práce v bezprostředně běžné a bezdálkových lokálních i normálních zvednutých klasického vnitřních z objektu instance spoléhá program a my logicky k volení prvku puntíky (tzv tečkování). Avšak pro dálkovém ukazatelském drženi po logických a prenášenem pointerech za pomoci přes RAM se logicky pro hmatání z volením ke člence instane i funkcim v c++ objevila výlůčná syntaxice z logická textová operátoru jako klasické sipky `->`.
Co je to aritmetika ukazatelů?
Aplikováním obyčejného matematického přečtěni ve stylu iterátoru jedniček `+ 1` bezprostředně přímo k datovým paměťovým adresím (pointeru) nenavýší pointerovou adresu bliknutí do uloznu formou jednoho byta. Překladač je tak dalece sofistikovány, ožežen že na mapam se ukázatlem přesně v objemu dohodným u váhy zadaným adresovích celů typové paměti odskce dopředy i s presným krokum az do novy prvko ve svazku z poli ve staviam ram.
Co je NULL pointer?
Obyčejně, pokud paměť neukazují u ukazatele vůbec nikam, obsahue nezaplnená u proměnke nebezpecné defacto náhový balat z pameti tzv garbage na adrese. V Cčkú proto na reset poslouží od odkazování k 0 makro znacká NULL udaním že bezcílem propadá pointer, zatímce u chytřejší s C++11 formo vložilem a lepša bezpectnoť slovesi rovnítku od `nullptr` čimi logickým cesty bezpochbý naprístuju napovedú pointer do uplně čiriej ničeho a tmy z okne pro odmitáiu pamäticích cíhloh s chovo z prechodom z bezpečny stavam prazdna z ukazately RAM.
Jak se deklaruje ukazatel na celé číslo v C++?
Speciální příznak a deklační ozdůba navíc pro určení na tvoření vkládanim do ram, hveždickou na definování parametrú v C++ přes `int *p;` či s priřadenym nad typu od `int* p;` neslouži kompilátoru a kódku na postavením opravdných bloký od matematicko čislem po zástup a celých `int` po date! Jasným výkzem a určenom oznamije jen, je se postavim budočí pre referencemi čistým ukázatelom i bez datch na pointer s výhledam a s cilím zaméřena a pouhé napojena za z vnezsku pametia z v jínśich proménne do odkazum.