EDIT: microtherion donne une excellente réponse qui corrige certains de mes points ici, en particulier sur l'utilisation de la mémoire.
Comme vous l'avez identifié, il existe certaines situations où vous êtes obligé d'utiliser un #define
, car le compilateur n'autorise pas une const
variable. De même, dans certaines situations, vous êtes obligé d'utiliser des variables, comme lorsque vous avez besoin d'un tableau de valeurs (c'est-à-dire que vous ne pouvez pas en avoir un #define
).
Cependant, il existe de nombreuses autres situations où il n'y a pas nécessairement une seule réponse «correcte». Voici quelques directives que je suivrais:
Sécurité des types
Du point de vue de la programmation générale, les const
variables sont généralement préférables (si possible). La principale raison en est la sécurité de type.
Une #define
(macro préprocesseur) copie directement la valeur littérale dans chaque emplacement du code, ce qui rend chaque utilisation indépendante. Cela peut hypothétiquement entraîner des ambiguïtés, car le type peut finir par être résolu différemment selon la façon dont il est utilisé.
Une const
variable n'est qu'un seul type, déterminé par sa déclaration et résolu lors de l'initialisation. Il nécessitera souvent une conversion explicite avant de se comporter différemment (bien qu'il existe diverses situations où il peut être implicitement promu par type en toute sécurité). À tout le moins, le compilateur peut (s'il est configuré correctement) émettre un avertissement plus fiable lorsqu'un problème de type se produit.
Une solution de contournement possible consiste à inclure une distribution explicite ou un suffixe de type dans a #define
. Par exemple:
#define THE_ANSWER (int8_t)42
#define NOT_QUITE_PI 3.14f
Cette approche peut cependant causer des problèmes de syntaxe dans certains cas, selon la façon dont elle est utilisée.
Utilisation de la mémoire
Contrairement à l'informatique à usage général, la mémoire est évidemment à un prix élevé lorsqu'il s'agit de quelque chose comme un Arduino. L'utilisation d'une const
variable par rapport à a #define
peut affecter l'emplacement de stockage des données en mémoire, ce qui peut vous obliger à utiliser l'une ou l'autre.
const
les variables seront (généralement) stockées dans SRAM, avec toutes les autres variables.
- Les valeurs littérales utilisées dans
#define
seront souvent stockées dans l'espace programme (mémoire Flash), à côté de l'esquisse elle-même.
(Notez que diverses choses peuvent affecter exactement comment et où quelque chose est stocké, comme la configuration et l'optimisation du compilateur.)
SRAM et Flash ont des limitations différentes (par exemple 2 Ko et 32 Ko respectivement pour l'Uno). Pour certaines applications, il est assez facile de manquer de SRAM, il peut donc être utile de déplacer certaines choses dans Flash. L'inverse est également possible, bien que probablement moins courant.
PROGMEM
Il est possible de bénéficier des avantages de la sécurité de type tout en stockant les données dans l'espace programme (Flash). Cela se fait à l'aide du PROGMEM
mot - clé. Cela ne fonctionne pas pour tous les types, mais il est couramment utilisé pour les tableaux d'entiers ou de chaînes.
La forme générale donnée dans la documentation est la suivante:
dataType variableName[] PROGMEM = {dataInt0, dataInt1, dataInt3...};
Les tables de chaînes sont un peu plus compliquées, mais la documentation contient tous les détails.