El operador de desreferencia o indirección , a veces denotado por " *
" (es decir, un asterisco ), es un operador unario (es decir, uno con un solo operando) que se encuentra en lenguajes similares a C que incluyen variables de puntero . Opera en una variable de puntero y devuelve un l-value
equivalente al valor en la dirección del puntero. Esto se llama "desreferenciar" el puntero. Por ejemplo, el código C
int x ; int * p ; // * se usa en la declaración: // p es un puntero a un número entero, ya que (después de desreferenciar), // * p es un número entero x = 0 ; // ahora x == 0 p = & x ; // & toma la dirección de x // ahora * p == 0, ya que p == & x y por lo tanto * p == x * p = 1 ; // equivalente ax = 1, ya que p == & x // ahora * p == 1 y x == 1
asignado 1 a la variable x
utilizando el operador de desreferencia y un puntero a la variable x
.
Composición
El operador unario *, como se define en C y C ++ , se puede utilizar en composiciones en casos de direccionamiento indirecto múltiple , donde se requieren múltiples actos de desreferenciación. Por supuesto, los punteros pueden hacer referencia a otros punteros y, en tales casos, se necesitan múltiples aplicaciones del operador de desreferencia. De manera similar, el operador de puntos de Java se puede usar en composiciones que forman declaraciones bastante sofisticadas que requieren una desreferenciación sustancial de punteros detrás de escena durante la evaluación.
Un ejemplo básico de indirección de múltiples punteros es el argumento argv para la función principal en C (y C ++) , que se da en el prototipo como char **argv
. El nombre del ejecutable del programa invocado, así como todos los argumentos de la línea de comandos que le siguieron, se almacenan como cadenas de caracteres independientes. Una matriz de punteros char
contiene punteros al primer carácter de cada una de estas cadenas, y esta matriz de punteros se pasa a la main
función como argv
argumento. La propia matriz pasada "decae" a un puntero, por argv
lo que en realidad es un puntero a un puntero a char
, aunque representa una matriz de punteros a char
(de manera similar, los punteros en la matriz, mientras que cada uno apunta formalmente a un único char
punto a lo que son cadenas de caracteres). El main
argumento que lo acompaña argc
, proporciona el tamaño de la matriz (es decir, el número de cadenas señaladas por los elementos de la matriz), ya que el tamaño de una matriz (más externa) se pierde cuando se pasa a una función y se convierte en una puntero. Por lo tanto, argv
es un puntero al elemento 0 de una matriz de punteros a char
, *argv
que a su vez es un puntero a **argv
un carácter (precisamente, el carácter 0 de la primera cadena de argumento, que por convención es el nombre del programa).
Otra sintaxis
En BCPL , un antepasado de C, el operador equivalente se representó mediante un signo de exclamación .
En C, la dirección de una estructura (o unión) s
se indica con &s
. La dirección del operador &
es la inversa del operador de desreferenciación *
, por lo que *&s
es equivalente a s
. La dirección de una estructura (o unión) s
puede asignarse a un puntero p
:
p = & s ; // la dirección de s se ha asignado ap; p == & s; // * p es equivalente a s
El valor de un miembro a
de una estructura s
se indica mediante s.a
. Dado un puntero p
a s
(ie p == &s
), s.a
es equivalente a (*p).a
, y también a la abreviatura p->a
que es azúcar sintáctica para acceder a los miembros de una estructura (o unión) a través de un puntero:
p = & s ; // la dirección de s se ha asignado ap; p == & s; // sa es equivalente a (* p) .a // sa es equivalente a p-> a // (* p) .a es equivalente a p-> a
El ->
operador puede estar encadenado; por ejemplo, en una lista vinculada, se puede hacer referencia al n->next->next
segundo nodo siguiente (asumiendo que n->next
no es nulo).
En los scripts de shell de Unix y en utilidades como Makefiles , el signo de dólar " $
" es el operador de desreferencia, utilizado para traducir el nombre de una variable a su contenido, y está notablemente ausente cuando se asigna a una variable.
En Pascal , el operador de desreferenciar ^ trabaja tanto para definir un puntero como para desreferenciarlo. Como muestra el siguiente ejemplo:
Tipo ComplexP = ^ TComplex ; (* ComplexP es un tipo de puntero *) TComplex = registro (* TComplex es un tipo de registro *) Re , Im : Entero ;VAR Complex1 , (* define dos punteros *) Complex2 : ComplexP ; Complejo : TComplex ; (* definir un registro *)empezar Complejo . Re : = 3,14159267 ; Complejo . Im : = 1,5 ; Nuevo ( Complex1 ) ; Complex1 ^. Re : = Complejo . Re ; Complex1 ^. Im : = 3,5 ; Nuevo ( Complex2 ) ; Complex2 ^ : = Complex ; FIN .
Int el ejemplo anterior
- En la línea 2, el operador de desreferencia ^ se usa para definir un tipo de puntero ComplexP .
- En las líneas 12 y 13, se asignan valores a la Re y Soy filelds del Registro complejo .
- En la línea 14, se asigna espacio para un Registro TComplex apuntado por Complejo1 ( Nuevo es el equivalente de C de Pascal función maloc () .)
- En la línea 15, el operador de desreferencia ^ se utiliza para copiar el valor en el Re campo de registro Complejo para el Re campo del Registro TComplex apuntado por Complejo 1 .
- En la línea 16, el operador de desreferencia ^ se utiliza para asignar un valor a la Soy campo de la Registro TComplex apuntado por Complejo 1 .
- En la línea 17, se asigna espacio para un Registro TComplex apuntado por Complejo 2 .
- En la línea 18, todo El registro complejo se copia al Registro TComplex apuntado por Complejo 2 .
En varios idiomas, los prefijos se utilizan en identificadores, conocidos como sigilos . Estos no son operadores unarios; sintácticamente son parte léxica del identificador y tienen una semántica diferente, como indicar el tipo de datos del identificador, pero son sintácticamente similares al operador de desreferencia y pueden confundirse con él. Por ejemplo, en un script de shell, $FOO
el operador de desreferencia se $
aplica a la variable FOO
, mientras que en Perl $foo
es una variable escalar llamada foo
. En PHP, FOO es una constante (definida por el usuario o incorporada), $ FOO es una variable denominada FOO y $$ FOO es una variable, cuyo nombre se almacena en la variable denominada FOO.