¿Qué son los punteros y cómo se usan?

por:

Que son los punteros y como 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.

Explicación simple de los punteros

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 (b5), 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.

Cómo se usan los punteros

En la imagen superior se puede ver cómo funcionan realmente los punteros. El carácter * representa a un puntero 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.

 

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
  • Fraciel Arevalo

    magnifica esplicasion me atrvo a decir que de tantos tutoriales y esplicasiones esta es la que mas clara me a quedadado