Dereference
Dereference je v programování operace, kterou se získává přístup k proměnné, na níž se odkazuje ukazatel nebo reference. V některých případech a jazycích je dereference implicitní (např. reference v C++), ve většině jazyků je však třeba použít unární operátor dereference.
Operátor dereference se zapisuje různě. V jazyce Pascal se na rozdíl od většiny ostatních jazyků zapisuje operátor za ukazatel; ve standardním Pascalu se pro dereferenci používá symbol šipka (↑
), který však není v mnoha znakových sadách obsažen, proto bývá nahrazován znakem stříška (^
) nebo zavináč (@
); v Turbo Pascalu se zavináč naopak používá pro získání adresy. V jazyce C se operátor dereference někdy nazývá indirection operator a používá se pro něj symbol hvězdička (*
). V mnoha skriptovacích jazycích se pro dereferenci používá symbol dolar ($
), který primárně slouží pro vyhodnocení obsahu proměnné.
Příklady použití
Jazyk C
Aplikací operátoru dereference na proměnnou, která je ukazatelem, je l-hodnota ekvivalentní hodnotě na adrese, na kterou ukazuje ukazatel. Tomuto se říká „dereferencování“ ukazatele. Například následující kód v jazyce C přiřadí hodnotu 1 do proměnné x
použitím operátoru dereference:
int x;
int *p; // použití * v deklaraci:
// p je ukazatel na integer, takže (po dereferencování)
// *p je integer
x = 0;
// nyní x == 0
p = &x; // & získá adresu proměnné x
// nyní *p == 0, protože p == &x a proto *p == x
*p = 1; // toto je ekvivalentem x = 1, protože p == &x
// nyní *p == 1 a x == 1
Vícenásobné použití
V jazycích C a C++ mohou ukazatelé ukazovat na ukazatele, a v takovém případě jsou potřebné vícenásobné aplikace operátoru dereference. Unární operátor * se pak v případech vícenásobných dereferencí může používat opakovaně. Podobně operátor tečka v jazyce Java lze používat při vytváření složitých výrazů, které při vyhodnocování vyžadují opakované dereferencování ukazatelů.
Jedním z příkladů vícenásobného použití dereference je práce s parametrem argv
funkce main
, který je v prototypu definován jako char **argv
. Běhová knihovna jazyka C uloží jméno, pod kterým byl vyvolán program, a parametry zadané za jménem programu na příkazovém řádku, jako samostatné znakové řetězce. Každý řetězec je reprezentován ukazatelem na char
, a jejich pole je předané do funkce main
jako parametr argv
. Předání pole se uskutečňuje předáním ukazatele na první prvek, takže argv
je ve skutečnosti ukazatel na ukazatel na char
, i když má význam pole ukazatelů na char
. Protože délku pole (počet řetězců v poli) nelze při předání ukazatele zjistit, je tato hodnota předána jakoo druhý parametr funkce main
, argc
. Takže argv
je ukazatel na 0. prvek pole ukazatelů na char
, tj. *argv
, který je zase ukazatelem na **argv
, což je 0. znak 0. argumentu, kterým je jméno programu.
Jiná syntaxe
V předchůdci jazyka C, v jazyce BCPL se pro dereferenci používá symbol vykřičník.
V jazyce C se adresa struktury (nebo unionu) s
označuje &s
. Adresa operátoru &
je inverzní operátor k dereferenci *
, takže *&s
je ekvivalentem s
. Adresa struktury (nebo unionu) s
může být přiřazena do ukazatele p
:
p = &s; // adresu s ulož do p; p == &s;
// *p je ekvivalentem s
Pro přístup k položce a
struktury s
se používá s.a
. Je-li dán ukazatel p
na s
(tj. p == &s
), pak zápis s.a
je ekvivalentem (*p).a
, což lze zkrátit na p->a
, což je syntaktický cukr pro přístup k položkám struktury (nebo unionu) pomocí ukazatele:
p = &s; // ulož adresu s do p; p == &s;
// s.a je ekvivalentem (*p).a
// s.a je ekvivalentem p->a
// (*p).a je ekvivalentem p->a
Operátory ->
lze řetězit; například ve spojovém seznamu se lze pomocí n->next->next
odkazovat na následníka následníka uzlu (za předpokladu, že n->next
není null).
V unixových shellových skriptech a programech jako make se znak dolar ($
) používá jako operátor pro získání hodnoty proměnné, který se při přiřazování do proměnné nepíše.
V různých jazycích se v identifikátorech používají prefixy známé jako sigily. Nejde o unární operátory – syntakticky jsou lexikální částí identifikátoru, a mají jinou sémantiku, např. indikují typ identifikátoru – ale jsou syntakticky podobné operátoru dereference a mohou se s nimi plést. Například in shellovém skriptu $FOO
je operátor dereference $
aplikován na proměnnou FOO
, zatímco v Perlu $foo
je proměnná nazývaná foo
. V PHP je FOO konstanta (definovaná uživatelem nebo vestavěná), $FOO je proměnná s jménem FOO a $$FOO je proměnná, jejíž jméno je uloženo v proměnné se jménem FOO.
Odkazy
Reference
V tomto článku byl použit překlad textu z článku Dereference operator na anglické Wikipedii.