EDITAR: microtherion da una excelente respuesta que corrige algunos de mis puntos aquí, particularmente sobre el uso de memoria.
Como ha identificado, hay ciertas situaciones en las que se ve obligado a usar a #define
, porque el compilador no permitirá una const
variable. Del mismo modo, en algunas situaciones se ve obligado a usar variables, como cuando necesita una matriz de valores (es decir, no puede tener una matriz de #define
).
Sin embargo, hay muchas otras situaciones en las que no hay necesariamente una sola respuesta "correcta". Aquí hay algunas pautas que seguiría:
Tipo de seguridad
Desde un punto de vista de programación general, las const
variables son generalmente preferibles (cuando sea posible). La razón principal de esto es la seguridad de tipo.
Una #define
(macro de preprocesador) copia directamente el valor literal en cada ubicación del código, haciendo que cada uso sea independiente. Hipotéticamente, esto puede dar lugar a ambigüedades, porque el tipo puede terminar resolviéndose de manera diferente dependiendo de cómo / dónde se use.
Una const
variable es solo un tipo, que se determina por su declaración y se resuelve durante la inicialización. A menudo requerirá una conversión explícita antes de que se comporte de manera diferente (aunque hay varias situaciones en las que puede promocionarse de forma implícita de forma segura). Como mínimo, el compilador puede (si está configurado correctamente) emitir una advertencia más confiable cuando ocurre un problema de tipo.
Una posible solución para esto es incluir una conversión explícita o un sufijo de tipo dentro de a #define
. Por ejemplo:
#define THE_ANSWER (int8_t)42
#define NOT_QUITE_PI 3.14f
Sin embargo, ese enfoque puede causar problemas de sintaxis en algunos casos, dependiendo de cómo se use.
Uso de la memoria
A diferencia de la informática de propósito general, la memoria es obviamente una prima cuando se trata de algo así como un Arduino. El uso de una const
variable vs. a #define
puede afectar el lugar donde se almacenan los datos en la memoria, lo que puede obligarlo a usar uno u otro.
const
las variables (generalmente) se almacenarán en SRAM, junto con todas las demás variables.
- Los valores literales utilizados a
#define
menudo se almacenarán en el espacio del programa (memoria Flash), junto con el propio boceto.
(Tenga en cuenta que hay varias cosas que pueden afectar exactamente cómo y dónde se almacena algo, como la configuración y optimización del compilador).
SRAM y Flash tienen limitaciones diferentes (por ejemplo, 2 KB y 32 KB respectivamente para el Uno). Para algunas aplicaciones, es bastante fácil quedarse sin SRAM, por lo que puede ser útil cambiar algunas cosas a Flash. Lo contrario también es posible, aunque probablemente sea menos común.
PROGMEM
Es posible obtener los beneficios de la seguridad de escritura mientras se almacenan los datos en el espacio del programa (Flash). Esto se hace usando la PROGMEM
palabra clave. No funciona para todos los tipos, pero se usa comúnmente para matrices de enteros o cadenas.
La forma general que figura en la documentación es la siguiente:
dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...};
Las tablas de cadenas son un poco más complicadas, pero la documentación tiene todos los detalles.