Dereferenční operátor - Dereference operator

Operátor dereference nebo operátor bezcílnost , někdy označován „ *“ (tj hvězdičkou ), je unární operátor (tedy jedna s jedinou operandu) nachází v C -jako jazyky, které zahrnují ukazatel proměnné. Funguje na proměnné ukazatele a vrací l-valueekvivalent k hodnotě na adrese ukazatele. Toto se nazývá „dereferencování“ ukazatele. Například kód C.

 int x;
 int *p;  // * is used in the declaration:
          // p is a pointer to an integer, since (after dereferencing),
          // *p is an integer
 x = 0;
 // now x == 0
 p = &x;  // & takes the address of x
 // now *p == 0, since p == &x and therefore *p == x
 *p = 1;  // equivalent to x = 1, since p == &x
 // now *p == 1 and x == 1

přiřazeno 1 proměnné xpomocí operátoru dereference a ukazatele na proměnnou x.

Složení

Unární * operátor, jak je definován v C a C ++ , může být použit v kompozicích v případech vícenásobné směry , kde je vyžadováno více aktů dereferencování. Ukazatele mohou samozřejmě odkazovat na jiné ukazatele a v takových případech je zapotřebí více aplikací dereferenčního operátora. Podobně může být operátor tečky Java použit v kompozicích tvořících poměrně sofistikovaná prohlášení, která vyžadují podstatné dereferencování ukazatelů v zákulisí během vyhodnocování.

Jednoduchý příklad vícenásobné ukazatele indirection je argv argumentem hlavní funkci v C (a C ++) , který je uveden v prototypu char **argv. Název spuštěného spustitelného programu a všechny argumenty příkazového řádku, které následovaly, jsou uloženy jako nezávislé znakové řetězce. Pole ukazatelů na charobsahuje ukazatele na první znak každého z těchto řetězců a toto pole ukazatelů je předáno mainfunkci jako argvargument. Samotné předané pole se „rozpadá“ na ukazatel, takže argvje ve skutečnosti ukazatelem na ukazatel na char, i když to znamená pole ukazatelů na char(podobně ukazatele v poli, přičemž každé formálně ukazuje na jeden char, ve skutečnosti bod k čemu jsou řetězce znaků). Doprovodný mainargument,, argcposkytuje velikost pole (tj. Počet řetězců, na které prvky pole ukazují), protože velikost (nejvzdálenějšího) pole je jinak ztracena, když je předána funkci a převedena na ukazatel. Je tedy argvukazatel na 0. prvek pole ukazatelů na char, *argvcož je naopak ukazatel na **argvznak (přesněji 0. znak prvního řetězce argumentů, který je podle konvence názvem programu).

Jiná syntaxe

V BCPL , předchůdci C, byl ekvivalentní operátor reprezentován pomocí vykřičníku .

V C je adresa struktury (nebo unie) soznačena &s. Adresa operátora &je inverzní k operátorovi dereferencing *, takže *&sje ekvivalentní s. Ukazateli smůže být přiřazena adresa struktury (nebo unie) p:

 p = &s; // the address of s has been assigned to p; p == &s;
 // *p is equivalent to s

Hodnota člena astruktury sje označena s.a. Vzhledem k tomu, že ukazatel pna s(tj. p == &s), s.aJe ekvivalentní k (*p).aa také na zkratku, p->acož je syntaktický cukr pro přístup k členům struktury (nebo unie) pomocí ukazatele:

 p = &s; // the address of s has been assigned to p; p == &s;
 // s.a is equivalent to (*p).a
 // s.a is equivalent to p->a
 // (*p).a is equivalent to p->a

->Operátor může být připoutaný; například v propojeném seznamu lze odkazovat na n->next->nextdruhý následující uzel (za předpokladu, že n->nextnení null).

Ve skriptování prostředí Unix a v nástrojích, jako jsou Makefiles , je znak dolaru " $" operátorem dereference, který se používá k překladu názvu proměnné do jejího obsahu, a při přiřazování proměnné zejména chybí.

V Pascalu funguje operátor dereference ^ jak pro definování ukazatele, tak pro jeho dereference. Jak ukazuje následující příklad:

Type
    ComplexP = ^TComplex;     (* ComplexP is a pointer type *)
    TComplex = record         (* TComplex is a record type *) 
       Re,
       Im: Integer;
VAR
    Complex1,                  (* define two pointers *)     
    Complex2: ComplexP;
    Complex : TComplex;         (* define a record *)

begin
     Complex.Re := 3.14159267;    
     Complex.Im := 1.5;           
     New(Complex1);               
     Complex1^.Re := Complex.Re;  
     Complex1^.Im := 3.5;         
     New(Complex2);               
     Complex2^ := Complex;        
END.

Int výše uvedený příklad

  • Na řádku 2 se operátor dereference ^ používá k definování typu ukazatele ComplexP .
  • Na řádcích 12 a 13 jsou přiřazeny hodnoty do polí Re a Im komplexního záznamu.
  • Na řádku 14 je přiděleno místo pro záznam TComplex, na který ukazuje Complex1 ( New je Pascalův ekvivalent funkce malloc () C. )
  • Na řádku 15 se operátor dereference ^ používá ke zkopírování hodnoty v poli Re záznamu Complex do pole Re záznamu TComplex, na který odkazuje Complex1 .
  • Na řádku 16 se operátor dereference ^ používá k přiřazení hodnoty Im poli záznamu TComplex, na který ukazuje Complex1 .
  • Na řádku 17 je přiděleno místo pro záznam TComplex, na který ukazuje Complex2 .
  • Na řádku 18 je celý komplexní záznam zkopírován do záznamu TComplex, na který ukazuje Complex2 .

V různých jazycích se předpony používají v identifikátorech, známých jako sigily . Nejedná se o unární operátory - syntakticky jsou lexikálně součástí identifikátoru a mají odlišnou sémantiku, například indikaci datového typu identifikátoru - ale jsou syntakticky podobné operátoru dereference a lze je s ním zaměňovat. Například ve skriptu Shell $FOOje operátor dereference $aplikovaný na proměnnou FOO, zatímco v Perlu $foose nazývá skalární proměnnáfoo . V PHP je FOO konstanta (definovaná uživatelem nebo vestavěná), $ FOO je proměnná s názvem FOO a $$ FOO je proměnná, jejíž název je uložen v proměnné s názvem FOO.

Viz také