Curso de C++ (Página 13b)

pagina013a Principal pagina013c

CAPITULO 13b Tipos de variables IV: Punteros 1

Correspondencia entre arrays y punteros:

Existe una equivalencia casi total entre arrays y punteros. Cuando declaramos un array estamos haciendo varias cosas a la vez:

La principal diferencia entre un array y un puntero es que el nombre de un array es un puntero constante, no podemos hacer que apunte a otra dirección de memoria. Además, el compilador asocia una zona de memoria para los elementos del array, cosa que no hace para los elementos apuntados por un puntero auténtico.

Ejemplo:

int vector[10]; 
int *puntero;
 
puntero = vector; /* Equivale a puntero = &vector[0]; 
  esto se lee como "dirección del elemento cero de vector" */ 
*puntero++; /* Equivale a vector[0]++; */ 
puntero++; /* entero == &vector[1] */ 

¿Qué hace cada una de estas instrucciones?:

La primera incrementa el contenido de la memoria apuntada por "entero", que es vector[0].

La segunda incrementa el puntero, esto significa que apuntará a la posición de memoria del siguiente "int", pero no a la siguiente posición de memoria. El puntero no se incrementará en una unidad, como tal vez sería lógico esperar, sino en la longitud de un "int".

Análogamente la operación:

puntero = puntero + 7; 

No incrementará la dirección de memoria almacenada en "puntero" en siete posiciones, sino en 7*sizeof(int).

Otro ejemplo:

struct stComplejo { 
   float real, imaginario; 
} Complejo[10]; 
 
stComplejo *p; 
p = Complejo; /* Equivale a p = &Complejo[0]; */ 
p++; /* entero  == &Complejo[1] */ 

En este caso, al incrementar p avanzaremos las posiciones de memoria necesarias para apuntar al siguiente complejo del array "Complejo". Es decir avanzaremos sizeof(stComplejo) bytes.

Operaciones con punteros:

Aunque no son muchas las operaciones que se pueden hacer con los punteros, cada una tiene sus peculiaridades.

Asignación.

Ya hemos visto cómo asignar a un puntero la dirección de una variable. También podemos asignar un puntero a otro, esto hará que los dos apunten a la misma posición:

int *q, *p;
int a;
 
q = &a; /* q apunta al contenido de a */ 
p = q; /* p apunta al mismo sitio, es decir, al contenido de a */ 

Operaciones aritméticas.

También hemos visto como afectan a los punteros las operaciones de suma con enteros. Las restas con enteros operan de modo análogo.

Pero, ¿qué significan las operaciones de suma y resta entre punteros?, por ejemplo:

int vector[10]; 
int *p, *q;
 
p = vector; /* Equivale a p = &vector[0]; */ 
q = &vector[4]; /* apuntamos al 5º elemento */ 
cout << q-p << endl; 

El resultado será 4, que es la "distancia" entre ambos punteros. Normalmente este tipo de operaciones sólo tendrá sentido entre punteros que apunten a elementos del mismo array.

La suma de punteros no está permitida.

Comparación entre punteros.

Comparar punteros puede tener sentido en la misma situación en la que lo tiene restar punteros, es decir, averiguar posiciones relativas entre punteros que apunten a elementos del mismo array.

Existe otra comparación que se realiza muy frecuente con los punteros. Para averiguar si estamos usando un puntero es corriente hacer la comparación:

if(NULL != p), o simplemente if(p) y también:

if(NULL == p), o simplemente if(!p).


pagina013a Principal pagina013c