logo

Ukazatele vs odkazy v C++

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?