Předpoklad: Ukazatele , Reference
123 film
C a C++ podporují ukazatele, což se liší od většiny ostatních programovacích jazyků, jako je Java, Python, Ruby, Perl a PHP, protože podporují pouze odkazy. Zajímavé ale je, že C++ spolu s ukazateli podporuje i odkazy.
Na první pohled jsou odkazy i ukazatele velmi podobné, protože oba se používají k tomu, aby jedna proměnná poskytovala přístup k jiné. Vzhledem k tomu, že oba poskytují spoustu stejných funkcí, často není jasné, co se mezi těmito mechanismy liší. V tomto článku se pokusím ilustrovat rozdíly mezi ukazateli a odkazy.
Ukazatele : Ukazatel je proměnná, která obsahuje paměťovou adresu jiné proměnné. Ukazatel je třeba dereferencovat pomocí * operátora pro přístup k umístění paměti, na které ukazuje.
Reference : Referenční proměnná je alias, tedy jiný název již existující proměnné. Odkaz, stejně jako ukazatel, je také implementován uložením adresy objektu.
Referenci si lze představit jako konstantní ukazatel (nezaměňovat s ukazatelem na konstantní hodnotu!) s automatickým směrováním, tj. kompilátor použije * operátor pro vás.
int i = 3; // A pointer to variable i or 'stores the address of i' int *ptr = &i; // A reference (or alias) for i. int &ref = i; >
Rozdíly :
1. Inicializace: Ukazatel lze inicializovat tímto způsobem:
int a = 10; int *p = &a; // OR int *p; p = &a; >
Můžeme deklarovat a inicializovat ukazatel ve stejném kroku nebo ve více řádcích.
2. V odkazech
int a = 10; int &p = a; // It is correct // but int &p; p = a; // It is incorrect as we should declare and initialize references at single step >
POZNÁMKA: Tento rozdíl se může lišit kompilátor od kompilátoru. Výše uvedený rozdíl je s ohledem na Turbo IDE.
3. Změna přidělení: Ukazatel lze znovu přiřadit. Tato vlastnost je užitečná pro implementaci datových struktur, jako je propojený seznam, strom atd. Viz následující příklad:
int a = 5; int b = 6; int *p; p = &a; p = &b; >
4. Na druhou stranu referenci nelze znovu přiřadit a musí být přiřazena při inicializaci.
int a = 5; int b = 6; int &p = a; int &p = b; // This will throw an error of 'multiple declaration is not allowed' // However it is valid statement, int &q = p; >
5. Adresa paměti: Ukazatel má svou vlastní paměťovou adresu a velikost v zásobníku, zatímco odkaz sdílí stejnou adresu paměti s původní proměnnou a nezabírá žádné místo v zásobníku.
int &p = a; cout << &p << endl << &a; >
6. Hodnota NULL: Ukazatel může být přiřazen přímo NULL, zatímco odkaz nemůže být. Omezení spojená s odkazy (žádná hodnota NULL, žádné opětovné přiřazení) zajišťují, že základní operace nenastanou výjimečné situace.
síťový operační systém
7. nepřímý směr: Můžete mít ukazatel na ukazatel (známý jako dvojitý ukazatel), který nabízí další úrovně nepřímosti, zatímco odkazy nabízejí pouze jednu úroveň nepřímosti. Například,
In Pointers, int a = 10; int *p; int **q; // It is valid. p = &a; q = &p; // Whereas in references, int &p = a; int &&q = p; // It is reference to reference, so it is an error >
8. Aritmetické operace: S ukazateli lze provádět různé aritmetické operace, přičemž neexistuje žádná taková věc, která se nazývá referenční aritmetika (můžete však provádět aritmetiku ukazatele na adrese objektu, na který odkazuje odkaz, jako v &obj + 5).
Tabulková forma rozdílu mezi odkazy a ukazateli v C++
| Reference | Ukazatele | |
|---|---|---|
| Přeřazení | Proměnnou nelze v Reference znovu přiřadit. | Proměnnou lze znovu přiřadit v ukazatelích. |
| Adresa paměti | Sdílí stejnou adresu jako původní proměnná. | Ukazatele mají svou vlastní paměťovou adresu. |
| Práce | Odkazuje na jinou proměnnou. | Ukládá adresu proměnné. |
| Nulová hodnota | Nemá hodnotu null. | Může mít hodnotu přiřazenou jako null. |
| Argumenty | Na tuto proměnnou se odkazuje metodou pass by value. | Ukazatel funguje metodou známou jako pass by reference. |
Kdy použít co
Výkony jsou přesně stejné jako reference jsou implementovány interně jako ukazatele. Přesto si můžete ponechat několik bodů, abyste se rozhodli, kdy co použít:
instanceof v jazyce Java
- Použijte reference:
- V parametrech funkcí a návratových typech.
- Použijte ukazatele:
- Pokud je potřeba aritmetika ukazatele nebo předání ukazatele NULL. Například pro pole (Všimněte si, že přístup k poli je implementován pomocí aritmetiky ukazatele).
- Implementovat datové struktury jako propojený seznam, strom atd. a jejich algoritmy. Je tomu tak proto, že abychom ukázali na různé buňky, musíme použít koncept ukazatelů.
Citováno v C++ FAQ Lite : Použijte odkazy, když můžete, a ukazatele, když musíte. Odkazy jsou obvykle upřednostňovány před ukazateli, kdykoli nepotřebujete znovu usadit. To obvykle znamená, že odkazy jsou nejužitečnější ve veřejném rozhraní třídy. Reference se obvykle objevují na povrchu objektu a ukazatele uvnitř.
Výjimkou z výše uvedeného je situace, kdy parametr nebo návratová hodnota funkce potřebuje sentinelový odkaz – odkaz, který neodkazuje na objekt. Toho se obvykle nejlépe dosáhne vrácením/převzetím ukazatele a přiřazením hodnoty nullptr této zvláštní důležitosti (odkazy musí být vždy aliasy objektů, nikoli dereferencovaný nulový ukazatel).
Související článek:
Kdy předáváme argumenty jako reference nebo ukazatele?