Beruflich Dokumente
Kultur Dokumente
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;
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;
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.
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;
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;
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.
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:
Espero que este artculo ayude a todos los que tengas dudas an sobre como usar los
punteros y las referencias de C/C++.