Punteros
Los punteros
permiten simular el paso por referencia, crear y manipular estructuras dinamicas
de datos, tales como listas enlazadas, pilas, colas y árboles. Generalmente las
variables contienen valores especificos. Los punteros son variables pero en vez
de contener un valor especifico, contienen las direcciones de las variables a
las que apuntan. Para obtener o modificar el valor de la variable a la que
apuntan se utiliza el operador de indirección. Los punteros, al ser variables
deben ser declaradas como punteros antes de ser utilizadas.
Sintaxis
int *ptrID, ID;
ID = 8;
ptrID = &ID; // puntero a ID
ptrID es un puntero
a int, mientras que la variable ID es solo una variable del tipo int. Todo
puntero debe ser precedido por un asterisco (*) en la
declaración.
Se puede declarar
más de un puntero en la misma sentencia. En el ejemplo que sigue se ve la
declaración de dos punteros a int.
int *ptrY, *ptrX;
Operadores
Existen dos
operadores a tener en cuenta cuando trabajamos con punteros. El operador
de dirección (&) que devuelve la dirección de memoria de su
operando y el operador de indirección (*) que devuelve un
alias para el objeto al cual apunta el operando del puntero.
En el siguiente
ejemplo vemos como se inicializa una variable X con el valor 15. Luego se crea
un puntero a int y por último el puntero pasa a apuntar a la variable X. Esto
es, ptrX es un puntero a X.
int X = 15;
int *ptrX;
ptrX = &X;
Punteros y matrices
Las matrices son
punteros constantes. Una matriz sin subindice es un puntero al primer elemento
de la matriz.
int X[15];
int *ptrX;
ptrX = &X; // ptrX recibe la dirección del primer elemento ( 0
) de X
Así como también
podría escribirse
int X[15];
int *ptrX;
ptrX = &X[0]; // ptrX es igual a la dirección del primer elemento
de X
Se pueden utilizar
distintos elementos de la matriz teniendo en cuenta la sintaxis de punteros.
int X[15], Y, *ptrX;
ptrX = X;
Y = *( ptrX + 7 );
En este caso puede
verse que Y toma el valor del elemento 7 de la matriz X, siendo 7 el
desplazamiento dentro de la matriz. El operador de indirección queda fuera del
paréntesis porque tiene una prioridad superior a la del operador +. De no
existir los paréntesis, se sumaria 7 al elemento X[0]. Teniendo en cuenta que
las matrices son punteros constantes, el nombre de la matriz puede tratarse
como un puntero:
Y = *( X + 7 );
Aritmética de Punteros
Al usar punteros a
matrices, hay que tener en cuenta que la aritmética cambia sensiblemente.
#include <iostream>
using std::cout;
using std::endl;
void main()
{
int X[6] = { 1, 2, 3, 4, 5, 6 };
int *prtX;
prtX = X; // incializo el
valor del puntero.
cout << endl << *prtX;
prtX += 2;
cout << endl << *prtX;
prtX -= 2;
cout << endl << *prtX;
prtX++;
cout << endl << *prtX;
}
atte: Oscar Torres & David Paz
En el siguiente
código, primero se crea un puntero a un arreglo de 6 elementos y si inicializa
el puntero prtX al primer elemento del arreglo X[0].
Si tenemos en cuenta que el siguiente ejemplo se ejecuta en una computadora con
enteros de 4 bytes, el segundo elemento de la matriz tendrá en memoria un
desplazamiento de 4 bytes, el 2 de ocho y asi sucesivamente. La operación prtX
+= 2; produce un desplazamiento llevándolo al 3 elemento dentro del
arreglo. Debe entenderse que prtX ahora apunta a una dirección de memoria y la
instrucción cambia esta dirección de memoria sumándole 2 multiplicado por el
tamaño del tipo de dato del arreglo que en este supuesto sería de 4. (dir
= ( dir + 2 * 4 )), dando por resultado un desplazamiento de 8 bytes. Sería
igual que ejecutar la operación prtX = &X[2];. La
operación prtX -= 2 obedece a la misma lógica estableciendo el
puntero al primer elemento del array X[0] y el operador ++
modifica el puntero desplazándolo 4 bytes y asignándole el segundo elemento de
la matriz.
Matrices de punteros
Para realizar una
estructura de datos dinámica, se puede utilizar una matriz donde sus elementos
sean punteros. Suponiendo que queramos hacer un calendario y lo dividamos por
semanas. Podríamos utilizar una matriz con los días de la semana.
const char *dias[7] = { "Domingo", "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sabado" }
Cada día de la
semana, no es un elemento de la matriz, sino que la expresión dias[7] crea una
matriz de siete elementos como punteros a char.
Formas de pasar un valor por referencia
Un puntero
constante a un dato no constante
#include <iostream>
void sumoeldoble( int * ); // prototipo
void main ()
{
int X = 15;
sumoeldoble( &X ); // Pasa la dirección
de memoria de X .
std::cout << X;
}
void sumoeldoble( int *ptrX )
{
// Toma el valor de
X mediante el operador de indirección
// La funcion no
devuelve nada porque modifica el valor por referencia.
*ptrX = *ptrX + ( *ptrX * 2 );
}
Un puntero no
constante a un dato constante
#include <iostream>
void imprimeChars( const char * ); // prototipo
void main ()
{
char cFrase[] = "Hola Mundo";
imprimeChars( cFrase );
}
void imprimeChars( const char *ptrStr )
{
for ( ; *ptrStr != '\0'; ptrStr++ ) //Sin
inicialización
std::cout << *ptrStr;
}
Un puntero
constante a un dato no constante
Un puntero es
constante cuando apunta siempre a la misma dirección de memoria y si el dato no
es constante entonces el valor puede ser modificado.
void main ()
{
int foo, bar;
int * const ptrFoo = &foo; // Apuntador constante a un entero en
la dirección de memoria de foo
*ptrFoo = 53;
// Esto devuelve un
error porque es un puntero constante.
// No se puede alterar
la dirección de memoria a la que apunta.
ptrFoo = &bar;
}
No hay comentarios:
Publicar un comentario