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-value
ekvivalent 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é x
pomocí 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 char
obsahuje ukazatele na první znak každého z těchto řetězců a toto pole ukazatelů je předáno main
funkci jako argv
argument. Samotné předané pole se „rozpadá“ na ukazatel, takže argv
je 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ý main
argument,, argc
poskytuje 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 argv
ukazatel na 0. prvek pole ukazatelů na char
, *argv
což je naopak ukazatel na **argv
znak (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) s
označena &s
. Adresa operátora &
je inverzní k operátorovi dereferencing *
, takže *&s
je ekvivalentní s
. Ukazateli s
můž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 a
struktury s
je označena s.a
. Vzhledem k tomu, že ukazatel p
na s
(tj. p == &s
), s.a
Je ekvivalentní k (*p).a
a také na zkratku, p->a
což 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->next
druhý následující uzel (za předpokladu, že n->next
není 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 $FOO
je operátor dereference $
aplikovaný na proměnnou FOO
, zatímco v Perlu $foo
se 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.