Anda di halaman 1dari 3

PUNTEROS

Un puntero es una variable que contiene la dirección de otra variable.


Los punteros son muy usados en C, principalmente porque:
 Permiten a las funciones modificar sus argumentos de llamada.
 Se utilizan para soportar rutinas de asignación dinámica de Turbo C.
 El uso de ellos mejora notablemente la eficiencia de ciertas rutinas.
 Se utilizan para implementar algunas estructuras de datos: listas enlazadas y árboles.
Los punteros, junto a la instrucción goto se asocian a la creación de programas imposibles de
comprender. Esto es verdad, cuando se usan sin cuidado, y es muy fácil crear punteros que
apunten a algún lugar inesperado. Con disciplina, sin embargo, los punteros también son
usados para alcanzar claridad y simplicidad. Éste es un aspecto que trataremos de ilustrar.

Conceptos Básicos

Veremos cómo se organiza la memoria de un computador. Una máquina típica tiene un arreglo
de celdas de memoria numeradas o direccionadas consecutivamente, que pueden manipularse
individualmente o en grupos contiguos. De esta forma, cualquier byte puede ser un char, un par
de bytes puede ser un entero y cuatro bytes consecutivos un entero largo. Un puntero es un
grupo de bytes (2 o 4) que pueden almacenar una dirección.
Como un puntero contiene la dirección de un objeto, es posible acceder al objeto
indirectamente a través del puntero.
Supongamos que x es una variable de tipo entero (int), px es un puntero creado de alguna
forma que todavía no conocemos.

px: x:

... ||| ||| ||| ||| .... ||| ||| ||| ||| ....
Figura 1: Una variable apuntando a otra

El operador unario & nos dará la dirección de un objeto. Así la instrucción


px = &x;
asigna la dirección de x a la variable px, se dice que px “apunta a ” x.
El operador & sólo se puede aplicar a variables y arreglos; no puede aplicarse a expresiones,
constantes o variables de tipo registro. Construcciones del tipo &(x + 1) y &3 son ilegales.
El dato representado por x, puede ser accedido mediante la expresión *px, donde * es el
operador unario, llamado operador indirección, que opera sólo sobre una variable puntero. Por
lo tanto, *px y x representan el mismo dato.
Cuando el operador * se aplica a un puntero, permite acceder al objeto al que señala el
puntero.

dirección de x valor de x
px x
Figura 2: Relación entre px y x (donde px = &x y x = *px)
Así, si y es una variable de tipo entero
y= *px;
asigna a y el contenido de cualquier cosa a la que apunte px
por lo tanto la secuencia
px = &x;
y = *px; asigna indirectamente el valor de x a y.
Es necesario también declarar las variables que participan en esto
int x,y;
int *px;

Ejemplo 1: Mostramos a continuación un programa sencillo que ilustra la relación entre dos
variables enteras, sus correspondientes direcciones y sus punteros asociados.
#include <stdio.h>
#include <conio.h>

void main()
{
int u = 3;
int v;
int *pu; /* puntero a un entero */
int *pv; /* puntero a un entero */

pu = &u; /* asigna la dirección de u a pu */


v = *pu; /* asigna el valor de u a v */
pv = &v; /* asigna la dirección de v a pv */
printf("\nu= %d &u= %X pu= %X *pu= %d", u, &u, pu, *pu);
printf("\n\nv= %d &v= %X p v= %X *pv= %d", v, &v, pv, *pv);
getch();
}
Notemos que pu es un puntero a u, y pv un puntero a v. Por tanto, pu representa la dirección de
u y pv la dirección de v.
La ejecución de este programa produce la siguiente salida

u= 3 &u= 12FF88 pu= 12FF88 *pu= 3


v= 3 &v= 12FF84 pv= 12FF84 *pv= 3

En la primera línea vemos que u tiene el valor 3, como está especificado en la instrucción de
declaración. La dirección de u está directamente determinada por el compilador como 12FF88
hexadecimal. Al puntero pu se le asigna este valor; por tanto pu también representa la dirección
12FF88 hexadecimal. Finalmente el valor al que apunta pu (el valor almacenado en la celda de
memoria cuya dirección es 12FF88) es 3.
Análogamente, la segunda línea muestra que v representa el valor 3. Esto era lo esperado, ya
que hemos asignado el valor *pu a v. La dirección de v, y por tanto el valor de pv es 12FF84.
Observemos que u y v tienen direcciones diferentes. Y finalmente, vemos que el valor al que
apunta pv es 3.

Declaración de punteros

Si una variable va a contener un puntero, debe declararse como tal.


La declaración de un puntero consiste de un tipo base, un * y el nombre de la variable.
La forma general de declaración de una variable puntero es:

tipo *nombre;
donde tipo es cualquier tipo válido de C (el tipo base del puntero) y nombre es el nombre de la
variable puntero.
El tipo base del puntero define el tipo de variables a las que puede apuntar el puntero.
Los dos operadores especiales de punteros son & y *.
& devuelve la dirección de memoria de su operando.
* es el complemento de &: devuelve el valor de la variable localizada en la
dirección que sigue.

Ejemplo 2: A continuación se muestra un sencillo programa en C.


#include <stdio.h>
#include <conio.h>

void main()
{
int u = 3;
int *pu;
pu = &u; /* pu apunta a u */
printf("\n*pu= %d u= %d", *pu, u);
*pu = 0; /* reasigna u indirectamente */
printf("\n\n*pu= %d u= %d", *pu, u);
getch();
}

El programa comienza asignando un valor inicial de 3 a la variable entera u y asignando la


dirección de u a la variable puntero pu. Así pu se convierte en un puntero a u. La expresión *pu
representa por tanto el valor 3. La primera instrucción printf() se usa para ilustrar esto al escribir
los valores actuales de *pu y u.
A continuación de la primera instrucción printf(), el valor de *pu es puesto a cero. Por tanto u
tendrá reasignado el valor cero. Esto se ilustra mediante la segunda instrucción printf(), que
hace que se escriban los nuevos valores de *pu y u.
Cuando se ejecuta el programa, se genera la siguiente salida:

*pu= 3 u= 3
*pu= 0 u= 0

Anda mungkin juga menyukai