Operador de desreferência - Dereference operator

O operador de desreferência ou operador de indireção , às vezes denotado por " *" (ou seja, um asterisco ), é um operador unário (ou seja, um com um único operando) encontrado em linguagens do tipo C que incluem variáveis ​​de ponteiro . Ele opera em uma variável de ponteiro e retorna um l-valueequivalente ao valor no endereço do ponteiro. Isso é chamado de "desreferenciamento" do ponteiro. Por exemplo, o código 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

atribuído 1 à variável xusando o operador de desreferência e um ponteiro para a variável x.

Composição

O operador unário *, conforme definido em C e C ++ , pode ser usado em composições em casos de múltiplas vias indiretas , onde múltiplos atos de desreferenciação são necessários. Os ponteiros podem, é claro, fazer referência a outros ponteiros e, em tais casos, vários aplicativos do operador de desreferência são necessários. Da mesma forma, o operador ponto Java pode ser usado em composições formando declarações bastante sofisticadas que requerem uma desreferenciação substancial de ponteiros nos bastidores durante a avaliação.

Um exemplo básico de indireção de múltiplos ponteiros é o argumento argv para a função principal em C (e C ++) , que é fornecido no protótipo como char **argv. O nome do executável do programa chamado, bem como todos os argumentos da linha de comando que se seguem, são armazenados como cadeias de caracteres independentes. Uma matriz de ponteiros para charcontém ponteiros para o primeiro caractere de cada uma dessas strings, e essa matriz de ponteiros é passada para a mainfunção como o argvargumento. A própria matriz passada "decai" para um ponteiro, portanto, argvé na verdade um ponteiro para um ponteiro para char, mesmo que represente uma matriz de ponteiros para char(da mesma forma, os ponteiros na matriz, enquanto cada um aponta formalmente para um único char, na verdade aponta para o que são cadeias de caracteres). O mainargumento que acompanha argc, fornece o tamanho do array (ou seja, o número de strings apontadas pelos elementos do array), já que o tamanho de um array (mais externo) é perdido quando é passado para uma função e convertido para um ponteiro. Portanto, argvé um ponteiro para o 0º elemento de uma matriz de ponteiros para char, *argvque, por sua vez, é um ponteiro para **argv, um caractere (precisamente, o 0º caractere da primeira string de argumento, que por convenção é o nome do programa).

Outra sintaxe

Em BCPL , um ancestral de C, o operador equivalente era representado por um ponto de exclamação .

Em C, o endereço de uma estrutura (ou união) sé denotado por &s. O endereço do operador &é o inverso do operador de desreferenciação *, portanto *&sé equivalente a s. O endereço de uma estrutura (ou união) spode ser atribuído a um ponteiro p:

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

O valor de um membro ade uma estrutura sé denotado por s.a. Dado um ponteiro ppara s(isto é p == &s), s.aé equivalente a (*p).a, e também para a abreviação p->aque é um açúcar sintático para acessar membros de uma estrutura (ou união) por meio de um ponteiro:

 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

O ->operador pode ser encadeado; por exemplo, em uma lista encadeada, pode-se referir-se ao n->next->nextsegundo nó seguinte (assumindo que n->nextnão seja nulo).

No shell scripting do Unix e em utilitários como Makefiles , o cifrão " $" é o operador de desreferência, usado para traduzir o nome de uma variável em seu conteúdo e está notavelmente ausente ao atribuir a uma variável.

Em Pascal , o operador de desreferência ^ funciona tanto para definir um ponteiro quanto para desreferenciá-lo. Como mostra o exemplo a seguir:

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.

No exemplo acima

  • Na linha 2, o operador de desreferência ^ é usado para definir um tipo de ponteiro ComplexP .
  • Nas linhas 12 e 13, os valores estão sendo atribuídos aos campos Re e Im do registro Complexo .
  • Na linha 14, o espaço é alocado para um registro TComplex apontado por Complex1 ( New é o equivalente em Pascal da função malloc () de C. )
  • Na Linha 15, o operador de desreferência ^ é usado para copiar o valor no campo Re do registro Complex para o campo Re do registro TComplex apontado por Complex1 .
  • Na linha 16, o operador de desreferência ^ é usado para atribuir um valor ao campo Im do registro TComplex apontado por Complex1 .
  • Na linha 17, o espaço é alocado para um registro TComplex apontado por Complex2 .
  • Na Linha 18, todo o registro Complex é copiado para o registro TComplex apontado por Complex2 .

Em várias línguas, os prefixos são usados ​​em identificadores, conhecidos como sigilos . Esses não são operadores unários - sintaticamente eles são parte lexicamente do identificador e têm semânticas diferentes, como indicar o tipo de dados do identificador - mas são sintaticamente semelhantes ao operador de desreferência e podem ser confundidos com ele. Por exemplo, em um script de shell $FOOé o operador de desreferência $aplicado à variável FOO, enquanto em Perl $fooé uma variável escalar chamada foo. No PHP, FOO é uma constante (definida pelo usuário ou embutida), $ FOO é uma variável chamada FOO e $$ FOO é uma variável, cujo nome é armazenado na variável chamada FOO.

Veja também