¿Qué es un puntero y cómo se usan?

Uno de los problemas más comunes a los que se enfrentan los usuarios que empiezan a programar en C o C++, es el uso de los punteros.

¿Qué es un puntero?

Un puntero no es más que una variable, en la cual se almacena una dirección de memoria. Esto parece muy simple, pero luego da muchos quebraderos de cabeza. Al ser una dirección de memoria, le podemos decir a un puntero que en ese lugar donde apunta queremos almacenar un valor, por ejemplo un número.

Para realizar una explicación muy sencilla, vamos a decir que un puntero es como un buzón de correos y nuestra memoria RAM, es similar a una comunidad de vecinos donde hay muchos buzones. Además en esta comunidad en lugar de tener el nombre puesto en el buzón, cada uno va a tener un identificador único.

Como se puede ver en la imagen, hay muchos buzones (zonas de memoria), pero no todas las podemos usar, ya que hay buzones que son nuestros y otros que son de otros vecinos (otros programas).

El buzón b5 tiene un papel con el número 23 escrito (en esa posición identificada como b5 está almacenado el número 23).

El buzón b1 es un puntero, ya que lo que tiene almacenado (b5), no es un valor, sino un identificador de otro buzón (una dirección de memoria).

¿Cómo se usa un puntero?

Una vez que ya sabemos que es un puntero, una variable cuyo valor es una dirección de memoria, vamos a proceder a explicar cómo se utilizan.

Imaginamos que el cartero sabiendo que hay dos buzones nuestros, decide introducir un paquete (el valor 23) en uno de nuestros buzones. Pero se da cuenta de que lo introdujo en el buzón que no era, entonces se le ocurre dejarnos en el buzón correcto (b1), un papel donde pone “tu paquete está en b5“.

La manera de obtener el valor es bien sencilla, nosotros abriríamos b1, veríamos que lo que hay dentro es el papel y entonces diríamos, para alcanzar el valor, tengo que ir a b5 y obtener su contenido.

En la imagen superior se puede ver cómo funcionan realmente los punteros. El carácter * representa a un puntero en C. Si quieres aprender este lenguaje te recomiendo este curso de programación en C.

En la dirección de memoria 0x67 tenemos almacenado un 5. Podemos decir que la variable cuya dirección de memoria es 0x67 es un entero o dicho de otra manera, que tenemos un entero de valor 5 almacenado en 0x67.

En la dirección de memoria 0x75 tenemos almacenado otra dirección de memoria, la 0x67. En este caso tenemos un puntero a entero, ya que tenemos en 0x75 almacenada la dirección de memoria de un entero. Es importante recalcar que tenemos dónde está el entero, no cual es su valor.

De igual manera, en la dirección 0x88 tenemos almacenado otra dirección de memoria, pero en este caso no es un puntero a entero, ya que la dirección de memoria almacenada no es la de un entero sino la de un puntero a entero. Esto da como resultado que tenemos un puntero a puntero a entero.

Como veis es fácil generalizar su funcionamiento partiendo de este ejemplo.

Respecto al uso dentro de un programa, los punteros se usan ya que permiten realizar operaciones de manera más eficiente al trabajar con direcciones de memoria. Por ejemplo si tuviéramos que intercambiar el valor de dos cadenas de texto de 200bytes cada una, es mucho más eficiente cambiar los punteros a cada una de las cadenas (2 bytes, uno por puntero), que copiar el contenido. El tener que gestionar manualmente estos punteros, quizás hacen de C un lenguaje complejo para empezar a programar.

 

Ejemplo práctico

Muchos se preguntarán todo esto está muy bien, pero es cierto o me están engañando. Para ello os dejamos el siguiente programa en C, que os puede servir para afianzar vuestros conocimientos con los punteros.

#include <stdio.h>
#include <stdlib.h>

int main(){
  int valor =5 ;
  int *p;
  int **pp;
  p=&valor;
  pp=&p;
  
  printf("Contenido en memoria: %8d  Direccion de memoria: %p  Tipo de dato: int\n", valor, &valor );
  printf("Contenido en memoria: %p  Direccion de memoria: %p  Tipo de dato: int*\n",p,&p);
  printf("Contenido en memoria: %p  Direccion de memoria: %p  Tipo de dato: int**\n",pp,&pp);
  printf("\n\nEl valor al que apunta mi puntero a entero es: %d",*p);
}
El resultado de la ejecución es: Contenido en memoria:        5
Direccion de memoria: 0x5fcaec  Tipo de dato: int Contenido en memoria: 0x5fcaec
Direccion de memoria: 0x5fcae0  Tipo de dato: int* Contenido en memoria: 0x5fcae0
Direccion de memoria: 0x5fcad8  Tipo de dato: int** El valor al que apunta mi puntero a entero es: 5

Como podéis ver:

  • Para declarar un puntero a entero se usa el asterisco: int *p
  • Para obtener la dirección de memoria dónde esta una variable utilizamos el carácter &
  • Para acceder al contenido de la dirección de memoria a la que apunta un puntero utilizamos el carácter * antecediéndolo al puntero.

 

Espero que este artículo os sea útil

Un saludo

The following two tabs change content below.

Jorge Durán

Entusiasta de la tecnología desde los 10 años, desarrollador y creador de varios proyectos de software y autodidacta por naturaleza. Ingeniero Informático por la USAL
Jorge Durán

Entusiasta de la tecnología desde los 10 años, desarrollador y creador de varios proyectos de software y autodidacta por naturaleza. Ingeniero Informático por la USAL

Share
Publicado por
Jorge Durán

Recent Posts

[Remix] Multitud de recursos para .NET

En los últimos tiempos no he podido escribir con toda la frecuencia que me gustaría,…

3 años hace

Los 10 mejores paquetes nuget que tienes que instalar

Cuando empiezas un proyecto hay una serie de aspectos comunes que suelen ser resueltos mediante…

3 años hace

Haz los mejores layouts y patrones CSS fácilmente

Si alguna vez has tenido que realizar un desarrollo de front-end seguramente te habrás dado…

4 años hace

10 lugares con retos y competiciones de programación

Una vez que una persona ya ha aprendido lo básico sobre un lenguaje de programación,…

4 años hace

¿Cómo elegir un buen hosting para tu proyecto?

Hoy en día, un gran porcentaje de los proyectos que se desarrollan son páginas webs.…

4 años hace

Cómo crear patrones CSS fácilmente en menos de un minuto

Hoy te muestro un recurso con el que crear patrones CSS con los que conseguir…

5 años hace