Beruflich Dokumente
Kultur Dokumente
1. APUNTADORES
Introduccin
Una de las caractersticas ms poderosas del lenguaje C++ es el manejo de apuntadores pues son de mucha utilidad en la manipulacin y acceso de datos teniendo en cuenta las direcciones en las que stos se encuentran guardados en la memoria. Adicionalmente, son muy tiles para pasar parmetros por referencia a funciones. Cuando se utilizan de manera incorrecta son tambin fuente de gran cantidad de errores.
Objetivo General
Estudiar la utilizacin de apuntadores, como una de las caractersticas ms poderosas del lenguaje C++.
Objetivos especficos
Aprender a relacionar un dato con su posicin de memoria. Manejar los apuntadores y su relacin con arreglos y funciones. Comprender la importancia de las variables de referencia y el paso por referencia en funciones.
1.1
Un apuntador es una de las caractersticas ms poderosas del lenguaje de programacin C++. Son variables que contienen direcciones de memoria en lugar de un valor especfico. Es decir, apuntan a la direccin de la memoria en la que est guardado el valor especfico de la variable. Suponga que la memoria es una matriz como la que se presenta en la siguiente figura. En la figura se pueden identificar dos tipos de variables: Las variables de color gris contienen valores especficos y estn ubicadas en las direcciones de memoria F1 y A3. Las variables de color azul son apuntadores. Estas variables contienen como valores las direcciones de memoria en las que se encuentran otras variables con valores especficos.
CENTRO DE SISTEMAS
A B C D E
F1 1
C3
De esta manera se puede ver que los apuntadores hacen referencia a valores especficos de manera indirecta. Para el caso del ejemplo, el apuntador de la posicin B1 hace referencia al valor A pero guardando la posicin de la memoria en la que ste se encuentra, es decir, F1.
Los apuntadores son como las direcciones en una ciudad. Las direcciones ubican las edificaciones dentro de la ciudad pero no hacen referencia directa a la edificacin. Adicionalmente, las edificaciones pueden ser diferentes tipos, tales como casas, edificios, almacenes, etc. De igual forma, los apuntadores pueden hacer referencia a cualquier tipo de variable. En el ejemplo observe que uno de los apuntadores hace referencia a una variable tipo int y otro a una variable tipo char. Hacer referencia a un valor a travs de un apuntador es conocido como indireccin.
1.1.1
Los apuntadores, al igual que todas las variables en C++, deben declararse antes de ser utilizados.
Por ejemplo, la siguiente lnea corresponde a la declaracin de un apuntador a una variable que contiene un valor de tipo double. La forma de leer la siguiente lnea es ptrVariable apunta a una variable tipo double.
double *ptrVariable;
La forma de declarar los apuntadores es declarar primero el objeto al que se va a apuntar y el nombre del apuntador se precede de un asterisco (*). Este asterisco indica que la variable ptrVariable es un apuntador a un double, es decir, que lo que se va a almacenar es una direccin de memoria.
En el siguiente ejemplo se presenta la creacin de una clase polinomio y la definicin de dos variables: una de tipo apuntador al polinomio llamada ptrPol y la otra de tipo polinomio llamada pol1.
class polinomio { int grado; double coeficientes [21]; //el grado mximo es 20
1.1.2
Una vez declarado un apuntador, ste debe ser inicializado. La inicializacin puede hacerse a una direccin de memoria o simplemente se puede inicializar el apuntador para que apunte a nada. Para inicializar el apuntador apuntando a nada se le debe asignar el valor 0 o NULL.
Para ilustrar la inicializacin considere el ejemplo polinomio del numeral anterior y ahora inicializaremos el apuntador a NULL.
class polinomio { int grado;
3
CENTRO DE SISTEMAS
1.2
OPERADORES DE APUNTADORES
Existen dos operadores principales que se utilizan cuando se trabaja con apuntadores: el operador de direccin (&) y el operador de indireccin (*), a continuacin se describe cada uno de ellos.
1.2.1 OPERADOR DIRECCIN
El operador direccin (&) es uno de los ms importantes de los definidos para variables de tipo apuntador. Devuelve la direccin en la que est guardada una variable.
ptrA=&a ;
La primera lnea define las variables int a y apuntador a int ptrA. La segunda instruccin le asigna al
4
apuntador ptrA la direccin de memoria en la que est guardada la variable a. En la siguiente figura se presentan una forma de interpretar el anterior ejemplo, en ella el apuntador se representa mediante una flecha que apunta a la variable a.
ptrA a 25
Las direcciones de memoria se trabajan en C++ como nmeros hexadecimales. En la siguiente tabla se presenta el mismo ejemplo pero utilizando las direcciones de memoria de las variables.
Nombre prtA A Direccin 03E8 07D0 Valor 07D0 25
1.2.2
OPERADOR INDIRECCIN
El operador indireccin (*) hace referencia al valor que tiene el objeto al que est haciendo referencia el apuntador.
Considere la siguiente lnea de cdigo. El resultado que se va a obtener es la impresin del valor de la variable a, es decir, 25.
cout << *ptrA << endl ;
Se llama operador de indireccin o desreferencia porque el procedimiento de modificar el valor del objeto al cual apunta se conoce como desreferenciacin.
CENTRO DE SISTEMAS
1.2.3
El uso del calificador const permite informar al compilador que determinada variable no debe ser modificada. Si durante un programa se intenta modificar una variable que se ha calificado como constante se despliega un mensaje de error o de advertencia.
Apuntador no constante a un dato no constante En este caso tanto el apuntador como el dato al que el apuntador hace referencia se pueden modificar. En este caso no se hace uso del calificador const. En el siguiente ejemplo se tiene un vector de nmeros tanto positivos como negativos y se convierten todos los nmeros negativos a cero, de modo tal que solo quedan nmeros positivos.
#include <iostream> using std::cout; using std::endl;
// Convierte el vector a nmeros positivos void conviertePositivo ( double *sPtr ) { while ( *sPtr != '\0' ) // ciclo hasta que se termine el vector 28 if ( *sPtr < 0 ) // si el nmero es negativo, *sPtr = 0; // lo convierte a 0 {
sPtr++; // mueve sPtr a la siguiente cadena de caracteres } // fin while } // fin funcin
CENTRO DE SISTEMAS
Apuntador no constante a un dato constante Un apuntador no constante a un dato constante es un apuntador que se puede modificar para que apunte a otro elemento pero dicho elemento no se puede modificar mediante el apuntador. En el siguiente ejemplo la funcin f trata de hacer una modificacin a un valor constante a travs de su apuntador. Esto devolver un error de compilacin.
void f( const int * ); int main() { int y; f( &y ); // f intenta una modificacin ilegal. return 0; } // fin main // xPtr no puede modificar el valor de la variable a la cual apunta void f( const int *xPtr ) { *xPtr = 100; // error: no se puede modificar un objeto const. } // end function f
Tomado de [3]
Apuntador constante a un dato no constante Un apuntador constante a un dato no constante es un apuntador que apunta siempre a la misma direccin de memoria pero el dato que se encuentra en dicha direccin se puede modificar utilizando el apuntador. En el siguiente ejemplo se intenta modificar un apuntador constante y se produce un error de compilacin.
int main() { int x, y; // ptr es un apuntador constante a un int // que puede modificarse pero siempre apunta // a la misma direccin. int * const ptr = &x; // el apuntador constante se debe inicializar. *ptr = 7; // permitido: *ptr no es constante. ptr = &y; // error: ptr es constante return 0; }
8
Tomado de [3]
Apuntador constante a un dato constante En este caso ni el apuntador ni el objeto al que el apuntador hace referencia pueden modificarse.
1.3
Al igual que las variables que se han trabajado hasta ahora, como int, double, etc., las variables de apuntador o apuntadores tambin se pueden manipular a travs de expresiones aritmticas, a continuacin se explica la forma de hacerlo.
1.3.1
EXPRESIONES
Los arreglos y los apuntadores estn ntimamente relacionados en C++. Un nombre de un arreglo se puede ver como un apuntador constante, es decir, si se declara un arreglo int a[5] y un apuntador int *ptrA, las dos siguientes expresiones son equivalentes entre s:
ptrA = a; ptrA= &a[0];
De la misma manera para hacer referencia al elemento 4 del arreglo las siguientes expresiones son equivalentes:
* (ptrA+4); a[4];
Esta expresin corresponde a la accin desplazamiento del apuntador y esta notacin es conocida como notacin apuntador/desplazamiento.
Por otro lado existe la notacin apuntador/subndice, mediante la cual para hacer referencia al elemento 4 del apuntador se utiliza la siguiente expresin:
ptrA[4];
1.3.2
OPERACIONES
En C++ se pueden realizar algunas operaciones con apuntadores. Las operaciones aritmticas que se realizan con apuntadores difieren de las operaciones aritmticas convencionales pues la
9
CENTRO DE SISTEMAS
aritmtica de apuntadores tiene en cuenta el tamao del objeto en memoria al que hace referencia el apuntador (nmero de bytes). La cantidad de memoria est determinada por el tipo de variable y en C++ la funcin sizeof permite conocer el tamao en bytes de cualquier objeto.
Algunas de las operaciones aritmticas que se pueden realizar con apuntadores son: Incremento (++). En la aritmtica convencional incrementar en uno un nmero es sumarle 1, es decir 5++ arroja 6. Sin embargo, en la aritmtica el operador ++ aumenta el apuntador no solamente en 1 sino en 1 multiplicado por el nmero de bytes que ocupa en memoria la variable a la que el apuntador hace referencia. Disminucin (--): La nueva posicin de memoria del apuntador se disminuye en 1 multiplicado por el nmero de bytes que ocupa en memoria la variable a la que el apuntador hace referencia. Sumar/restar un entero a un apuntador (+/- +=/-=): Al igual que los anteriores operadores sumar o restar tiene en cuenta el nmero de bytes de las variables. Sumar o restar apuntadores del mismo tipo. Asigna a la nueva variable el nmero de elementos que hay entre los apuntadores.
Por ejemplo, se declara un vector de tamao 4, int x[4] y supondremos que su primer elemento se encuentra ubicado en la posicin 1000, en general, las variables de tipo int tienen un tamao en memoria de 4 bytes. Se define adems un apuntar a la primera posicin del vector xPtr:
int x[4]; xPtr=x;
A continuacin se presentan algunas operaciones que se pueden realizar con el apuntador a este vector. Operacin Apuntador original 1000 1004
x[0]
Grfica
1008
x[1]
1012
x[2] x[4]
xPtr
10
1008
x[1]
1012
x[2] x[4]
xPtr
1008
x[1]
1012
x[2] x[4]
xPtr
Por otro lado se puede asignar un apuntador a otro si estos son del mismo tipo. As mismo, existen comparaciones de igualdad y relaciones.
Resumen
Los apuntadores son variables que almacenan direcciones de otras variables. La declaracin de los apuntadores se hace utilizando el asterisco (*). La expresin int * aPrt declara un apuntador a una variable de tipo int. Los apuntadores deben inicializarse, generalmente a una direccin de memoria o a ninguna parte usando 0. Existen dos operadores fundamentales con apuntadores: Operador direccin (&): Devuelve la direccin de una variable en memoria. Operador indireccin (*): Devuelve un sinnimo para el nombre de objeto al que el apuntador hace referencia. Los apuntadores se pueden utilizar para pasar y modificar variables por referencia a funciones. Con apuntadores se pueden realizar operaciones aritmticas de sumar o restar enteros. Estas operaciones suman o restan dependiendo del tamao de la variable a la que el apuntador hace referencia.
11
CENTRO DE SISTEMAS
Los apuntadores pueden asignarse entre s siempre y cuando sean del mismo tipo.
Actividades complementarias
Escriba un programa que muestre como diferentes tipos de apuntadores se pueden utilizar para recorrer arreglo que almacene datos de diferentes tipos. Escriba el cdigo de la siguiente funcin, que retorna la suma de elementos de tipo double apuntados por los n primeros apuntadores del arreglo p: double suma (double *p[ ], int n).
Lecturas recomendadas
JOYANES, Luis J., Programacin en C++, Algoritmos, estructuras de datos y objetos. Editorial Mc Graw Hill, 2 Edicin 2002. Pginas 197 a 214.
Arnush Craig, Aprendiendo Borland C++ 5 en 21 das. Editorial Prentice Hall. Pginas 127 a 145.
SMITH JO ANN, C++ Desarrollo de Proyectos. Editorial Paraninfo, 2001. Pginas 149 a 160.
12