Sie sind auf Seite 1von 8

Punteros y referencias

Muchos novatos o gente que viene de lenguajes de alto nivel no quieren ni or hablar de
C/C++. se oyen cosas como que es muy complicado porque hay que manejar la memoria a
bajo nivel, no tiene recolector de basura, etc. Vamos a intentar explicar claramente el
manejo de memoria en C/C++ y los temidos punteros y referencias.

La memoria principal
Como sabemos cuando declaramos una variable lo que estamos haciendo es reservar una
zona de memoria, imaginemos que la memoria es una tabla con muchas celdas:

Imaginemos que cada celda de memoria puede ser ocupada por un dato. En realidad segn
el tipo dato se precisan ms o menos casillas, pero para entender el concepto imaginemos
que en cada casilla se puede almacenar un dato. Nuestra memoria ficticia est compuesta de
mil casillas numeradas desde el 0 al 999. sta es la direccin de memoria de cada casilla, su
identificador nico, como pudieran ser en la vida real una direccin de una calle, un
nmero y un piso.
Si nosotros hacemos algo como esto en nuestro cdigo:
int x = 4;

Lo que estamos haciendo es reservar una zona de memoria para una variable x y dndole el
valor 4. Imaginemos que en nuestra memoria ficticia se almacena en la posicin 998, se
vera as.

Bien, en C++ hay un operador para obtener la direccin de memoria de una variable y es &
si hiciramos algo como imprimir el valor de la direccin de memoria:
int x = 4;
cout << "Valor de x: " << x << endl;
cout << "Direccion de x: " << &x << endl;

Nos saldra por pantalla:


Valor de x: 4
Direccion de x: 998

Realmente no te saldr un nmero entero sino que ser un nmero hexadecimal bastante
ms largo, pero hay que tener bastante claro que ni el nmero hexadecimal que te de el
compilador ni el 998 son nmeros enteros es una direccin de memoria un tipo de dato
como cualquier otro.

Punteros
Como es un tipo de dato las direcciones de memoria se pueden almacenar en variables.
Variables del tipo que almacenan direcciones de memoria que son los llamados punteros.
Por tanto un puntero es tan solo un tipo de datos como int almacena enteros, char caracteres

o float almacena nmeros de como flotante pues los punteros almacenan direcciones de
memoria.
La clave est en que no hay una palabra clave, valga la redundancia, para definir a los tipos
punteros sino que segn sea el tipo de direccin que va a almacenar ese sera el tipo
aadiendo el operador *.
Por ejemplo si yo quiero crear un puntero que almacene una direccin de memoria de un
entero debo hacer lo siguiente:
int *px;

con esto estoy declarando una variable que puede almacenar la direccin de una variable de
tipo int. Podriamos entonces asignarle una direccin de memoria mediante el operador que
vimos antes.
int x = 4;
int *px = &x;

Imaginemos que la variable px se crea en la posicin 2 de nuestra memoria ficticia. Nos


quedara el siguiente esquema:

Como vemos ocupa una posicin como una variable normal, pero en lugar de contener un
entero como 4 contiene una direccin de memoria (998). Como posicin de memoria que
ocupa tambin tiene su direccin de memoria que se puede obtener con el operador & es lo
que se llama un puntero de puntero.

Estos se declaran igual que los dems anteponiendo el operador *:


int x = 4;
int *px = &x;
int **ppx = &px // es un puntero de puntero por lo que solo puede guardar
direcciones de punteros de tipo int

Siguiendo con el ejemplo de nuestra memoria ficticia supongamos que la nueva variable
ppx se crea en la posicin 997. Este sera el equema resultante.

El operador de indireccin
Bien, ya sabemos almacenar en memoria direcciones de memoria de otras variables ya sean
variables enteras o de cualquier tipo como punteros de las mismas (punteros de punteros).
Ahora necesitamos algo para poder usar esas direcciones de memoria, poder usarlas para
acceder al contenido original, esto se hace a travs del operador de indireccin * y no, no
me he equivocado es el mismo que se usa para declarar los punteros es lo que tiene C y por
tanto C++ que reutiliza mucho los operadores y basa su significado en el contexto. Veamos
un ejemplo de uso.
int x =
int *px
cout <<
cout <<

4;
= &x;
"Valor de x: " << x << endl;
"Valor de x: " *px << endl;

Esto mostrar el siguiente resultado:

Valor de x: 4
Valor de x: 4

Como vemos anteponer * a una variable puntero nos devuelve el contenido de la direccin
que contiene. Lo mismo sucede con los punteros de punteros:
int x = 4;
int *px = &x;
int **ppx = &px;
cout << "Valor de x: " << x << endl;
cout << "Valor de x: " << *px << endl;
cout << "Valor de x: " << **ppx << endl;

La ltima sentencia el asterisco ms pegado a la variable devuelve la que contiene la


direccin de ppx que es px y el siguiente asterisco devuelve lo que contiene la direccin de
px que es x y por tanto 4.
Valor de x: 4
Valor de x: 4
Valor de x: 4

Paso por valor o por referencia


Una de las cosas ms tiles de los punteros es el paso por referencia en lugar del paso por
valor. Vamos a explicar como funciona esto en C/C++.

mbito de variables
Lo primero es entender bien lo que es el mbito de las variables, una variable solo existe en
la funcin en la que se crea y nada ms, a travs de los parmetros podemos pasar el valor
de una determinada variable a otra funcin, pero lo que pasamos es el valor y no la variable
en s. Veamos un ejemplo.
#include <iostream>
void sumar(int);
int main()
{
int n = 4;
sumar(n);
std::cout << n << std::endl;
system("pause");
return 0;
}
void sumar(int x)
{
x++;
std::cout << x << std::endl;
}

Tenemos la funcin main que contiene la variable n, esta variable solo existe en este
contexto al llamar a la funcin sumar que tiene como parmetro la variable x lo que
hacemos es darle a ese valor del parmetro x el valor de n, pero es la nica relacin que hay
entre n y x por tanto la salida de nuestro programa es la siguiente:
5
4

La variable x que vala 4 por el valor que le dio n es aumentada en una unidad y se muestra
en pantalla, se sale de la funcin sumar y se vuelve a la funcin main que muestra el valor
de n que sigue siendo 4.

Paso por referencia


Hay veces que nos interesa que una funcin modifique una variable que no pertenece a ella,
es decir, fuera de su mbito. En C/C++ es imposible pasar una variable por referencia como
en otros lenguajes y hay que hacerlo a travs de punteros (o referencias como veremos ms
adelantes). La idea es que como solo se puede pasar el valor de una variable a una funcin
lo que hacemos es pasar la direccin de una variable a travs de un parmetro de puntero y
luego con el operador de indireccin podemos acceder al contenido de la variable original.
#include <iostream>
void sumar(int *);
int main()
{
int n = 4;
sumar(&n);
std::cout << n << std::endl;
system("pause");
return 0;
}
void sumar(int *x)
{
*x = *x + 1;
std::cout << *x << std::endl;
}

Como vemos el parmetro de sumar ahora es un puntero que recibe una direccin de
memoria en este caso le pasamos la direccin de la variable x y dentro de la funcin con
operador de indireccin podemos acceder al contenido de la variable n.

Referencias
Adems de los punteros heredados de C el lenguaje C++ aadi una nueva caracterstica
que son las referencias, una referencia es por as decirlo un alias o etiqueta de una variable.
Las referencias se deben inicializar al declararse ya que no son en s una variable sino una
etiqueta de otra y se declaran poniendo el operador & despus del tipo de dato.

int n = 4;
int &ref_n = n;
std::cout << ref_n << std::endl;

A efectos prcticos n y ref_n se refieren a la misma variable de hecho si con el operador &
obtenemos la direccin de memoria de n y ref_n obtendramos la misma en ambos casos.
En nuestra memoria ficticia se vera as:

Paso por referencia con referencias


Las referencias son una buena forma de pasar un valor a otra funcin sin ser por valor,
veamos el ejemplo anterior de paso por punteros, pero est vez usando referencias.
#include <iostream>
void sumar(int &);
int main()
{
int n = 4;
sumar(n);
std::cout << n << std::endl;
system("pause");
return 0;
}
void sumar(int &x)
{
x = x + 1;
std::cout << x << std::endl;
}

Espero que este artculo ayude a todos los que tengas dudas an sobre como usar los
punteros y las referencias de C/C++.

Das könnte Ihnen auch gefallen