|
||
Ukazatele - 2.částV předchozí části této lekce jsme si vysvětlili princip funkce ukazatelů a ukázali jsme si pár základních příkladů, jak je možné ukazatele použít. Na tyto znalosti navážeme v této části, kde si ukážeme další vlastnosti ukazatelů. Ukazatele a poleZ předchozí části víme, že pokud ukazatel odkazuje na nějakou proměnnou, tak hodnotou tohoto ukazatele je právě adresa dané proměnné. Dále víme, že paměť počítače je realizována souvislou řadou očíslovaných buněk o velikosti 1B. Proto některé proměnné zaberou více buněk a jiné zase méně, v závislosti na datovém typu. Vezměme si například proměnnou typu float:
float pepe;
Proměnná tohoto typu má velikost 4B, proto zabere v paměti 4 buňky(101, 102, 103, 104): Dále vytvořme ukazatel, který na tuto proměnnou bude odkazovat:
float *tom;
Každý ukazatel, bez ohledu na to jekého je typu, má velikost 1B. To znamená, že může vždy uchovávat adresu pouze jedné buňky paměti. Proto i v našem příkladě bude uchovávat adresu pouze jedné buňky a to i přesto, že odkazuje na proměnnou o velikosti 4B. Konkrétně to bude adresa první buňky, tedy 101. Znamená to tedy, že adresa proměnné odpovídá prvnímu elementu této proměnné - v tomto případě paměťové buňce.Na stejném principu pracují také pole. Mějme například následující pole:
int adam[5];
Proměnná adam je ve skutečnosti ukazatel, který konstantně ukazuje na první prvek pole, tj. prvek s indexem nula. Proto říkáme že proměnná adam je tzv. konstantní ukazatel. Pro lepší představu si ukážeme následující příklad:
#include <iostream>
V příkladě jsme deklarovali pole adam o rozměru 2 a ukazatel pepe. Pojďme si podrobně popsat hlavní funkci programu: Hned na prvním řádku narazíme na příkaz pepe = adam;, čímž ukazatelipepe říkáme kam má odkazovat. Nyní je potřeba si uvědomit, že proměnná adam je rovněž ukazatel, který konstantně ukazuje na první prvek pole adam. Proto nepoužijeme operátor reference (&). Příkaz pepe = adam; tedy znamená: Přiřaď ukazeteli pepe adresu na kterou odkazuje ukazatel adam. Na následujícím řádku pomocí ukazatele pepe přistoupíme k prvku pole sindexem 0 a uložíme do něj hodnotu 777. Dostáváme se ke třetímu řádku hlavní funkce s příkazem: pepe = adam + 1;. Tento příkaz opět uloží do ukazatele pepe adresu na kterou odkazuje ukazateladam. V tomto případě však adresu o 1 vyšší. Ukazateladam konstantně ukazuje na adresu 101. Z toho plyne že ukazatelipepe bude přiřazena adresa 101 + 1 = 102. Následně opět přistoupíme k prvku pole pomocí ukazatele pepe. Tentokrát však budeme přistupovat k prvku s adresou 102 a uložíme do něj číslo 999. Nakonec necháme vypsat hodnoty obou prvků pole na obrazovku:
Prvek pole s indexem 0: 777
Inicializace ukazateleVždy když chceme vytvořit ukazatel, tak nejprve provedeme jeho deklaraci a poté mu přiřadíme adresu nějakého elementu (provedeme inicializaci). Například:
int *pepe;
Deklaraci a inicializaci však můžeme provést v jednom kroku. V takovém případě ovšem musíme proměnnou na kterou se bude odkazovat, deklarovat jako první:
int adam;
Ukazetele odkazující na jiné ukazateleV jazyce C++ ukazatele nemusí nutně odkazovat pouze na proměnné, mohou totiž odkazovat i na jiné ukazatele. Podívejme se na následující příklad:
int pepe = 77;
První věcí, která jistě upoutá Vaši pozornost, jsou 2 hvězdičky u ukazateletom. Tento zápis nemá žádnou speciální funkci oproti tomu s jednou hvězdičkou, je však v tomto případě nazbytný, jelikož ukazatel tom je o úroveň níže než ukazateladam. Pro lepší představu se podívejme na tuto ilustraci: Počet hvězdiček u ukazatele tedy určuje úroveň tohoto ukazatele. Laicky řečeno, to je vzdálenost od proměnné. Zatímco ukazatel adam je od proměnnépepevzdálen 1 krok, tak ukazatel tom je vzdálen 2 kroky -proto 2 hvězdičky. S každým dalším o úroveň nižším ukazatelem by jsme přidali další hvězdičku. Pro ověření správnosti tohoto příkladu jsme nechali vypsat hodnotu proměnné, ne kterou odkazuje ukazatel tom. V tomto případě opět použijeme 2 hvězdičky, jako operátor dereference:
77
Ukazatel typu voidUkazatel typu void je spaciální ukazatel, který může odkazovat na elementlibovolného datového typu. Tento ukazatel je deklarován stejně jako všechny ostaní, pouze s tím rozdílem, že místo datového typu uvedeme klíčové slovo void. Například:
void *pepe;
Tento ukazatel tedy může odkazovat na elementy libovolného typu:
void *pepe;
Jak můžete vidět v této ukázce, pomocí jednoho ukazatele můžeme odkazovat na proměnné o třech různých datových typech (int, char, float). Problém však nastane ve chvíli, kdy budeme chtít pomocí operátoru dereference přistopit k hodnotě proměnné na kterou je odkazováno. Tento postup totiž povede k chybě.To je způsobeno tím, že ukazatel neví na jaký datový typ ukazuje. Proto nemůžeme k hodnotě proměnné, na kterou je odkazováno, přistoupit. V takovém případě si budeme muset vypomoci ještě jedním ukazatelem, jehož datový typ je shodný s datovým typem proměnné. To však ještě nebude stačit, jelikož adresu na kterou odkazuje ukazatel typu void můžeme přiřadit opět pouze ukazateli typu void. Proto budeme muset ukazatel void přetypovat na požadovaný datový typ, viz příklad:
int adam = 77;
Přetypování proběhne na zvýrazněném řádku. Jelikož je proměnná adam typu int, přetypujeme ukazatel pepe rovněž na typ int. Pro ověření spávnosti necháme vypsat hodnotu, na kterou odkazuje ukazatel tom:
77
NULL ukazatelNULL ukazatel je klasický ukazatel libovolného datového typu (ne však void), obsahující hodnotu NULL (nula), která značí, že neodkazuje na žádnou platnou adresu v paměti. Například:
int *pepe;
|
Počítadlo |
| Nahoru
Úvod |
HTML |
CSS |
C++ |
JavaScript |
Grafika & design |
Webhosting
|