logo

Ukazovatele vs referencie v C++

Predpoklad: Ukazovatele , Referencie

C a C++ podporujú ukazovatele, čo sa líši od väčšiny ostatných programovacích jazykov, ako sú Java, Python, Ruby, Perl a PHP, pretože podporujú iba odkazy. Ale zaujímavé je, že C++ spolu s ukazovateľmi podporuje aj referencie.



Na prvý pohľad sú odkazy aj ukazovatele veľmi podobné, pretože obidva sa používajú na to, aby jedna premenná poskytovala prístup k inej. Keďže oba poskytujú veľa rovnakých možností, často nie je jasné, čo sa medzi týmito mechanizmami líši. V tomto článku sa pokúsim ilustrovať rozdiely medzi ukazovateľmi a referenciami.

Ukazovatele : Ukazovateľ je premenná, ktorá obsahuje pamäťovú adresu inej premennej. Ukazovateľ je potrebné dereferencovať pomocou * operátorovi na prístup k umiestneniu pamäte, na ktoré ukazuje.

Referencie : Referenčná premenná je alias, teda iný názov už existujúcej premennej. Odkaz, podobne ako ukazovateľ, je tiež implementovaný uložením adresy objektu.
Referenciu možno považovať za konštantný ukazovateľ (nezamieňať s ukazovateľom na konštantnú hodnotu!) s automatickým smerovaním, t. j. kompilátor použije * operátor pre 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;>

Rozdiely :

1. Inicializácia: Ukazovateľ možno inicializovať týmto spôsobom:

int a = 10; int *p = &a; // OR  int *p; p = &a;>

Ukazovateľ môžeme deklarovať a inicializovať v rovnakom kroku alebo vo viacerých riadkoch.



2. V referenciách

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 rozdiel sa môže líšiť od kompilátora k kompilátoru. Vyššie uvedený rozdiel sa týka Turbo IDE.

3. Preradenie: Ukazovateľ je možné znova priradiť. Táto vlastnosť je užitočná na implementáciu dátových štruktúr, ako je prepojený zoznam, strom atď. Pozrite si nasledujúci príklad:

int a = 5; int b = 6; int *p; p = &a; p = &b;>

4. Na druhej strane referenciu nie je možné opätovne priradiť a musí byť priradená pri inicializácii.

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äte: Ukazovateľ má svoju vlastnú pamäťovú adresu a veľkosť v zásobníku, zatiaľ čo referencia zdieľa rovnakú pamäťovú adresu s pôvodnou premennou a nezaberá žiadne miesto v zásobníku.

int &p = a; cout << &p << endl << &a;>

6. Hodnota NULL: Ukazovateľ môže byť priradený priamo NULL, zatiaľ čo odkaz nie. Obmedzenia spojené s referenciami (žiadna NULL, žiadne opätovné priradenie) zaisťujú, že základné operácie sa nedostanú do situácie výnimky.

7. Nepriame: Môžete mať ukazovateľ na ukazovateľ (známy ako dvojitý ukazovateľ), ktorý ponúka ďalšie úrovne nepriamej orientácie, zatiaľ čo odkazy ponúkajú iba jednu úroveň nepriamej orientácie. Naprí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é operácie: S ukazovateľmi je možné vykonávať rôzne aritmetické operácie, zatiaľ čo referenčná aritmetika neexistuje (aritmetiku ukazovateľa však môžete vykonávať na adrese objektu, na ktorý odkazuje odkaz, ako v &obj + 5).

Tabuľková forma rozdielu medzi referenciami a ukazovateľmi v C++

Referencie Ukazovatele
Preradenie Premennú nie je možné opätovne priradiť v referencii. Premennú je možné znova priradiť v Ukazovateloch.
Adresa pamäte Zdieľa rovnakú adresu ako pôvodná premenná. Ukazovatele majú svoju vlastnú pamäťovú adresu.
Práca Odkazuje na inú premennú. Ukladá adresu premennej.
Nulová hodnota Nemá nulovú hodnotu. Môže mať hodnotu priradenú ako null.
Argumenty Na túto premennú sa odkazuje metódou pass by value. Ukazovateľ funguje metódou známou ako prechod odkazom.

Kedy použiť Čo

Výkony sú úplne rovnaké, pretože referencie sú implementované interne ako ukazovatele. Stále si však môžete ponechať niekoľko bodov, aby ste sa rozhodli, kedy čo použiť:

  • Použite referencie:
    • V parametroch funkcií a typoch návratov.
  • Použite ukazovatele:
    • Ak je potrebná aritmetika ukazovateľa alebo odovzdanie ukazovateľa NULL. Napríklad pre polia (Všimnite si, že prístup k poli je implementovaný pomocou aritmetiky ukazovateľa).
    • Implementovať dátové štruktúry ako prepojený zoznam, strom atď. a ich algoritmy. Je to tak preto, že na to, aby sme ukázali na rôzne bunky, musíme použiť koncept ukazovateľov.

Citované v C++ FAQ Lite : Používajte odkazy, keď môžete, a ukazovatele, keď musíte. Referencie sú zvyčajne uprednostňované pred ukazovateľmi vždy, keď nepotrebujete opätovné usadenie. Zvyčajne to znamená, že odkazy sú najužitočnejšie vo verejnom rozhraní triedy. Odkazy sa zvyčajne objavujú na povrchu objektu a ukazovatele vo vnútri.

Výnimkou z vyššie uvedeného je situácia, keď parameter funkcie alebo návratová hodnota potrebuje referenciu sentinelu – referenciu, ktorá neodkazuje na objekt. To sa zvyčajne najlepšie vykoná vrátením/prevzatím ukazovateľa a priradením hodnoty nullptr tejto špeciálnej dôležitosti (odkazy musia byť vždy alias objekty, nie dereferencovaný nulový ukazovateľ).

Súvisiaci článok:
Kedy odovzdávame argumenty ako referencie alebo ukazovatele?