arduino-punteros

En esta lección vamos a continuar con lo que vimos en Variables en Arduino, así que es importante que si no has leído ese post lo hagas ahora ya que partiremos de ahí para aprender sobre punteros.

Como vimos en “Variables en Arduino” el uso de variables nos permite almacenar ciertos datos y operar con ellos a lo largo del código de nuestro proyecto. Estos datos se guardan en un lugar concreto de la memoria de nuestra placa controladora, es decir, asociada a la variable en la que creemos que tendremos un contenido (valor que almacenamos) y una dirección de memoria que nos indica donde se guarda dicho valor. Pero, ¿cómo podemos saber dicha dirección? Para ello se recurre al operador & que se puede traducir al lenguaje natural como “la dirección de”.

Vamos a aplicar lo que aprendimos sobre comunicación por el Puerto Serie para mostrar por el monitor serial un ejemplo para ver la diferencia entre contenido y dirección de memoria:

Como puedes ver, para poder imprimir la dirección de memoria tenemos que hacer una pequeña modificación. La memoria de la placa Zum Core es de 32 kb, por lo que serán necesarias 32.768 direcciones de memoria distintas. Para cubrir todas las combinaciones posibles, las direcciones de memoria se codifican con 2 bytes (16 bits). Es por eso que al imprimir la dirección de memoria donde está almacenada la variable se hace lo que se llama una conversión de tipo (casting) que hace que el valor de &a sea interpretado como una variable de tipo entero sin signo (unsigned int) y no un entero (int), ya que en éste no caben direcciones de memoria suficientes. Pero, ¿podemos guardar esta dirección para poder trabajar con ella?

Punteros

Los punteros son un tipo de variables especialmente preparados para almacenar una dirección física de un objeto en el mapa de memoria. Podemos imaginar los punteros como una marca que apunta a otra variable (o posición de memoria), a través de la cual también podremos acceder a la información guardada en la posición a la que apunta el puntero. Por esto es importante que el puntero que declaremos sea del mismo tipo que la variable a la que va a apuntar. Un momento, ¿cómo se declaran los punteros?

Los punteros se declaran de la siguiente manera:

Donde tipo es el tipo de variable a la que va a apuntar el puntero y nombre_puntero es el nombre por el que llamaremos a la variable puntero que se está declarando
Veamos algunos ejemplos:

Como hemos dicho antes, todas las variables tienen una dirección de memoria asociada en donde se guarda la información que contiene la variable y, como podrás imaginar, los punteros no son diferentes. Un puntero tiene asociada una dirección de memoria en donde guarda a su vez otra dirección de memoria de otra variable a la que apunte. ¿Que lío no? Vamos a verlo con un ejemplo. Antes de que copies el código en tu IDE de Arduino te reto a que recuerdes lo que vimos en el post sobre la LCD y hagas lo mismo que hago yo aquí pero mostrando la información por la pantalla de la LCD.

Esto es lo que me ha salido a mí, aunque a ti te pueden salir otros valores para las direcciones de memoria.
Selección_051

Por si no ha quedado del todo claro vamos a representarlo gráficamente (recuerda que son variables tipo int y unsigned int por lo que ocupan 2 bytes o 16bits):


Valor Decimal Valor Binario
100 00000000 01100100
2294 00001000 11110110
2292 00001000 11110100


arduino-punteros-ejemplo

Los punteros, como una variable más, pueden definirse como variables globales o locales tal y como se explicó en la lección sobre Variables en Arduino

Aritmética de punteros

La aritmética de punteros nos permite sumar/restar un valor entero al puntero, de forma que podemos mover el puntero y recorrer la memoria de una forma determinada por el tipo de variable con que se declara el puntero y el valor entero con que se opere. De forma genérica si tenemos:

Será como desplazar nuestro puntero n veces el número de bytes definido por el tipo de variable con que se declara el puntero; volviendo al ejemplo anterior, si tenemos:

Es equivalente al resto de tipos de variables, a continuación puedes ver gráficamente este tipo de operaciones:

arduino-punteros-ejemplos

Para operar con punteros podemos utilizar la misma sintaxis que con el resto de variables:

¿Y para que sirven? (¿Y para qué no?)

OJO Como hemos visto, cuando se utilizan punteros se accede a datos a través de la dirección de memoria en donde están guardados. Es importante que en todo momento conozcamos a donde apunta el puntero que estamos usando o podríamos acabar sobreescribiendo zonas de memoria en las que no sabemos que hay. Actualmente los sistemas operativos tienen la memoria protegida de forma que no te dejarán sobreescribir zonas de memoria ajenas a tu programa, pero una vez en tu placa no hay sistema operativo que proteja tus datos. Por esto es imprescindible inicializar los punteros nada más declararlos, para ello puedes apuntarlos a otra variable o darles un valor nulo (que no apuntará a ningún sitio concreto).

Los punteros son muy útiles para recorrer información con una estructura de datos determinada, ya que podremos ir desplazando el puntero por la memoria con esa misma estructura pudiendo acceder, leer y escribir los datos de forma ordenada. En nuestro caso, para programar en Arduino por norma general no trabajaremos con ficheros de información por lo que esta aplicación no nos interesa demasiado. El uso de punteros nos permite utilizar estructuras de datos complejas, como pueden ser vectores, estructuras, etc., que explicaremos y usaremos en otras lecciones, además permite trabajar con variables dinámicas, que se crean y destruyen durante la ejecución del programa, aunque esto último es más avanzado.