miércoles, 21 de abril de 2010

Apuntadores en C++

Los apuntadores en C y C++ son una herramienta muy potente de programación que suele causar mucha confusión en los estudiantes que la están aprendiendo.

Cuando se declara una variable, el compilador reserva un espacio de memoria para ella y asocia el nombre de esta a la dirección de memoria desde donde comienzan los datos de esa variable. Las direcciones de memoria se suelen describir como números en hexadecimal.

Un apuntador
Es una variable cuyo valor es la dirección de memoria de otra variable. Se dice que un apuntador “apunta” a la variable cuyo valor se almacena a partir de la dirección de memoria que contiene el apuntador. Por ejemplo, si un apuntador p almacena la dirección de una variable x, se dice que “p apunta a x”.

La Referenciación
Es la obtención de la dirección de una variable. En C y C++ esto se hace através del operador ‘&’, aplicado a la variable a la cual se desea saber su dirección. Nótese que se trata de un operador unario.
Ejemplo:
------------------------------------------------------------------------
Codigo C++

int x = 25;
cout << "La dirección de x es: " << &x <<>------------------------------------------------------------------------

Este código imprime un valor del estilo “0x4fffd34”. Este valor puede variar durante cada ejecución del programa, debido a que el programa puede reservar distintos espacios de memoria durante cada ejecución. Para declarar un apuntador se especifica el tipo de dato al que apunta, el operador ‘*’, y el nombre del apuntador. La sintaxis es la siguiente: *

A continuación se muestran varios ejemplos:

-------------------------------------------------------------------------
Código C++
int *ptr1; // Apuntador a un dato de tipo entero (int)
char *cad1, *cad2; // Dos apuntadores a datos de tipo carácter (char)
float *ptr2; // Apuntador a un dato de tipo punto-flotante (float)
-------------------------------------------------------------------------

Se pueden asignar a un apuntador direcciones de variables a través del operador de referenciación (‘&’) o direcciones almacenadas en otros apuntadores. Ejemplos:

-------------------------------------------------------------------------------
Código C++

int i = 5;
int *p, *q;
p = &i; // Se le asigna a ’p’ la dirección de ’i’
q = p; // Se le asigna a ’q’ la dirección almacenada en ’p’ (la misma de ’i’)
--------------------------------------------------------------------------------

La Desreferenciacion
Es la obtención del valor almacenado en el espacio de memoria donde apunta un apuntador. En C y C++ esto se hace a través del operador ‘*’, aplicado al apuntador que contiene la dirección del valor. Nótese que se trata de un operador unario. Ejemplos:

---------------------------------------------------------------------------------
Código C++

int x = 17, y;
int *p;
p = &x;
cout << "El valor de x es: " << *p << y =" *p">
---------------------------------------------------------------------------------

C++ además provee el operador binario ‘->’, utilizado para obtener campos de un registro con un apuntador al mismo de una manera mas fácil y legible. Muchos compiladores de C también soportan este operador.
Ejemplo 2:

---------------------------------------------------------------------------------
Código C++
struct Data
{
char nombre[20];
int edad;
};
Data d;
Data *pd = &d;
(*pd).edad = 23; // Acceso al campo ’edad’ utilizando el operador ’.’
pd->edad = 23; // Acceso al campo ’edad’ utilizando el operador ’->’
---------------------------------------------------------------------------------------

Tipos de Apuntadores

Apuntadores A Apuntadores
Dado que un apuntador es una variable que apunta a otra, fácilmente se puede deducir que pueden existir apuntadores a apuntadores, y a su vez los segundos pueden apuntar a apuntadores, y así sucesivamente. Estos apuntadores se declaran colocando tantos asteriscos (‘*’) como sea necesario. Ejemplo:
------------------------------------------------------------------------------
Código C y C++
char c = ’z’;
char *pc = &c;
char **ppc = &pc;
char ***pppc = &ppc;
***pppc = ’m’; // Cambia el valor de c a ’m’
------------------------------------------------------------------------------

Apuntadores Constantes U Apuntadores A Constantes
Es posible declarar apuntadores constantes. De esta manera, no se permite la modificación de la dirección almacenada en el apuntador, pero s´ı se permite la modificación del valor al que apunta. Ejemplo:
------------------------------------------------------------------------------

Código C y C++
int x = 5, y = 7;
int *const p = &x; // Declaración e inicialización del apuntador constante
*p = 3; // Esto es valido
p = &y; // Esto no es valido (el compilador genera un error)
------------------------------------------------------------------------------

También es posible declarar apuntadores a datos constantes. Esto hace que no sea posible modificar el valor al que apunta el apuntador. Ejemplo:
------------------------------------------------------------------------------

Código C y C++
int x = 5, y = 7;
const int *p = &x; // Declaración e inicialización del apuntador a constante
p = &y; // Esto es valido
*p = 3; // Esto no es valido (el compilador genera un error)
y = 3; // Esto es valido
------------------------------------------------------------------------------

Apuntadores, Arreglos y Aritmética de Apuntadores
Los arreglos y apuntadores están fuertemente relacionados. El nombre de un arreglo es simplemente un apuntador constante al inicio del arreglo. Se pueden direccionar arreglos como si fueran apuntadores y apuntadores como si fueran arreglos. Ejemplos:
------------------------------------------------------------------------------

Código C y C++
int lista_arr[5] = {10, 20, 30, 40, 50};
int *lista_ptr;
lista_ptr = lista_arr; // A partir de aqu´ı ambas variables apuntan al mismo sitio
cout << p =" &lista[3];" p =" lista" q =" cad;" p =" &x[1]," q =" &x[4];" n =" q">Apuntadores Para Paso De Parámetros Por Referencia
El lenguaje C no provee una manera de pasar parámetros por referencia. Sin embargo, es posible hacerlo a través del uso de apuntadores. A continuación se muestra un ejemplo del paso de un parámetro por referencia en C++, y luego un código equivalente en C o C++ utilizando un apuntador:
------------------------------------------------------------------------------

Código C++
void suma(int a, int b, int& r)
{
r = a + b;
}
void main()
{
int x;
suma(7, 5, x);
cout << "7 + 5 = " << r =" a" 5 =" ">

Bibliografía
El presente articulo fue realizado con la ayuda del libro “Programacion en C++”, del autor Luis Joyanes Aguilar, editorial Mc Graw Hill.


1 comentario:

  1. Muy bueno el post! completo y legible! No olvide de hacer uso de fotos y videos!

    ResponderEliminar