Saltar al contenido

¿Es mejor usar #define o const int para constantes?

Solución:

Es importante tener en cuenta que const int lo hace no se comportan de manera idéntica en C y en C ++, por lo que, de hecho, varias de las objeciones en su contra que se han aludido en la pregunta original y en la extensa respuesta de Peter Bloomfields no son válidas:

  • En C ++, const int Las constantes son valores de tiempo de compilación y pueden usarse para establecer límites de matriz, como etiquetas de caso, etc.
  • const int las constantes no ocupan necesariamente ningún almacenamiento. A menos que tome su dirección o los declare externos, generalmente solo tendrán una existencia en tiempo de compilación.

Sin embargo, para constantes enteras, a menudo puede ser preferible usar un (con nombre o anónimo) enum. A menudo me gusta esto porque:

  • Es compatible con versiones anteriores de C.
  • Es casi tan seguro como const int (cada bit tan seguro en C ++ 11).
  • Proporciona una forma natural de agrupar constantes relacionadas.
  • Incluso puede usarlos para cierta cantidad de control del espacio de nombres.

Entonces, en un programa idiomático de C ++, no hay razón alguna para usar #define para definir una constante entera. Incluso si desea seguir siendo compatible con C (debido a requisitos técnicos, porque lo está haciendo a la vieja usanza o porque las personas con las que trabaja lo prefieren de esa manera), aún puede usar enum y debería hacerlo, en lugar de usar #define.

EDITAR: microterión da una excelente respuesta que corrige algunos de mis puntos aquí, particularmente sobre el uso de la memoria.


Como ha identificado, hay ciertas situaciones en las que se ve obligado a utilizar un #define, porque el compilador no permitirá const variable. De manera similar, 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 única respuesta “correcta”. Aquí hay algunas pautas que seguiría:

Tipo de seguridad

Desde un punto de vista de programación general, const las variables suelen ser preferibles (cuando sea posible). La principal razón de ello es la seguridad de tipos.

A #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 resultar en ambigüedades, porque el tipo puede terminar resolviéndose de manera diferente dependiendo de cómo / dónde se use.

A const La variable es solo un tipo, que se determina mediante 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 se puede promover implícitamente el tipo 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 un #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 memoria

A diferencia de la informática de propósito general, la memoria es obviamente escasa cuando se trata de algo como un Arduino. Usando un const variable vs. a #define puede afectar dónde se almacenan los datos en la memoria, lo que puede obligarlo a utilizar uno u otro.

  • const las variables (normalmente) se almacenarán en SRAM, junto con todas las demás variables.
  • Valores literales utilizados en #define a menudo se almacenará 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 la 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 menos común.

PROGRAMA

Es posible obtener los beneficios de la seguridad de tipos al mismo tiempo que se almacenan los datos en el espacio del programa (Flash). Esto se hace usando el PROGMEM palabra clave. No funciona para todos los tipos, pero se usa comúnmente para matrices de números enteros o cadenas.

La forma general dada en el documentación es como sigue:

dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...}; 

Las tablas de cadenas son un poco más complicadas, pero la documentación tiene todos los detalles.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *