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.

Související články