Pourquoi les gens utilisent-ils une variable pour spécifier un numéro de code PIN lorsque le code PIN est peu susceptible de changer tout au long de l'exécution du code?
Plusieurs fois, je vois un int
être utilisé pour une définition de broche,
int led = 13;
lorsque l'utilisation d'un const int
const int led = 13;
#define LED 13
est beaucoup plus logique.
C'est même dans les tutoriels sur le site Arduino, par exemple, le premier tutoriel que la plupart des gens exécutent, Blink .
J'ai lu quelque part qui const int
est préféré à #define
. Pourquoi cela n'est-il pas encouragé dès le début, plutôt que de permettre aux gens de développer de mauvaises habitudes, dès le départ? Je l'ai remarqué il y a quelque temps, mais récemment, il a commencé à m'énerver, d'où la question.
En ce qui concerne la mémoire / le traitement / l'informatique, est-ce que const int
, enum
ou d'ailleurs #define
, mieux qu'une simple int
, c'est-à-dire occupe moins de mémoire, stockée dans une mémoire différente (Flash, EEPROM, SRAM), exécution plus rapide, compilation plus rapide?
Cela peut sembler être un doublon de Est-il préférable d'utiliser #define ou const int pour les constantes? , mais j'aborde la question de savoir pourquoi les gens utilisent des variables et comment les performances s'améliorent quand elles ne le font pas, plutôt que quel type de constante est meilleur.
la source
Réponses:
C'est la bonne méthode. Ou même:
Combien de broches avez-vous?
Certains didacticiels n'ont pas tout à fait subi autant de contrôle de la qualité qu'ils auraient pu.
Les performances seront meilleures à utiliser
const byte
, comparez à,int
mais le compilateur peut être suffisamment intelligent pour réaliser ce que vous faites.Ce que vous pouvez faire est d'encourager doucement les gens à utiliser des techniques plus efficaces en les utilisant dans votre propre code.
Réponses aux commentaires
Un commentateur a suggéré que ce
byte
n'est pas la norme C. C'est correct, mais il s'agit d'un site Arduino StackExchange, et je pense que l'utilisation de types standard fournis par l'IDE Arduino est acceptable.Dans Arduino.h, il y a cette ligne:
Notez que ce n'est pas exactement le même que
unsigned char
. Voir uint8_t vs caractère non signé et quand uint8_t char caractère non signé? .Un autre intervenant a suggéré que l'utilisation d'octets n'améliorera pas nécessairement les performances, car des nombres plus petits que ceux
int
qui seront promusint
(voir Règles de promotion d'entiers si vous en voulez plus).Cependant, dans le contexte d'un identificateur const , le compilateur générera un code efficace dans tous les cas. Par exemple, le démontage du "clignotement" donne ceci sous la forme originale:
En fait, il génère le même code que
13
:#define
const int
const byte
Le compilateur sait quand il peut rentrer un nombre dans un registre et quand il ne le peut pas. Cependant, il est recommandé d'utiliser un codage qui indique votre intention . Le faire
const
indique clairement que le nombre ne changera pas et le faitbyte
(ouuint8_t
) indique clairement que vous attendez un petit nombre.Messages d'erreur déroutants
Une autre raison majeure à éviter
#define
est les messages d'erreur que vous obtenez si vous faites une erreur. Considérez ce croquis "clignotant" qui a une erreur:En surface, il semble OK, mais il génère ces messages d'erreur:
Vous regardez la première ligne en surbrillance (ligne 4) et ne voyez même pas de symbole "=". De plus, la ligne semble bien. Maintenant, il est assez évident de savoir quel est le problème ici (
= 13
est remplacéLED
), mais lorsque la ligne se trouve 400 lignes plus loin dans le code, il n'est pas évident que le problème réside dans la façon dont la LED est définie.J'ai vu des gens tomber à plusieurs reprises (y compris moi-même).
la source
int
c'est exagéré ... c'est-à-dire jusqu'à ce qu'Arduino finisse par sortir avec la carte Tera ... :-)byte
type . Tu veux direunsigned char
.byte
au lieu deint
, car dans la plupart des contextes, une valeur entière avec des types plus petits que ceuxint
promusint
.C doesn't have a byte type. You mean unsigned char.
- Ma réponse était dans le contexte Arduino, qui a celatypedef uint8_t byte;
. Donc, pour un Arduino, l'utilisationbyte
est OK.Performance won't necessarily be better with byte instead of int
- voir poste modifié.Comme le dit à juste titre Ignacio, c'est essentiellement parce qu'ils ne savent pas mieux. Et ils ne savent pas mieux parce que les gens qui les ont enseignés (ou les ressources qu'ils ont utilisées pour apprendre) ne savaient pas mieux.
Une grande partie du code Arduino et des didacticiels sont rédigés par des personnes qui n'ont jamais reçu de formation en programmation et sont très "autodidactes" à partir de ressources par des personnes qui sont elles-mêmes très autodidactes sans formation appropriée en programmation.
De nombreux extraits de code de didacticiel que je vois autour de moi (et en particulier ceux qui ne sont disponibles que dans les vidéos YouTube --- urgh) seraient une note d'échec si je les notais lors d'un examen.
Oui, a
const
est préféré à un non-const, et même à a#define
, car:const
(comme un#define
, contrairement à un non-const) n'alloue pas de RAMconst
(comme un non-const, mais contrairement à a#define
) donne à la valeur un type expliciteLe deuxième point est particulièrement intéressant. Sauf indication contraire avec le transtypage de type intégré (
(long)3
) ou un suffixe de type (3L
) ou la présence d'un point décimal (3.0
),#define
un nombre sera toujours un entier et toutes les mathématiques effectuées sur cette valeur seront comme s'il s'agissait d'un entier. La plupart du temps, ce n'est pas un problème, mais vous pouvez rencontrer des scénarios intéressants lorsque vous essayez#define
une valeur plus grande qu'un entier peut stocker, comme#define COUNT 70000
et ensuite effectuer une opération mathématique avec d'autresint
valeurs. En utilisant un,const
vous pouvez dire au compilateur "Cette valeur doit être traitée comme ce type de variable" - vous utiliseriez donc à la place:const long count = 70000;
et tout fonctionnerait comme prévu.Il a également pour effet d'activer le contrôle du type lors du passage de la valeur autour de l'endroit. Essayez de passer un
const long
à une fonction qui attend unint
et il se plaindrait de réduire la plage de variables (ou même de ne pas compiler complètement selon le scénario). Faites cela avec un#define
et cela continuerait silencieusement à vous donner les mauvais résultats et vous laisserait vous gratter la tête pendant des heures.la source
const
variable peut nécessiter de la RAM, selon le contexte, par exemple si elle est initialisée à l'aide de la valeur de retour d'une fonction non constexpr.const int foo = 13; bar(&foo);
faudra certainement que le compilateur alloue la mémoire réelle pourfoo
.int
le compilateur traite la valeur comme ayant le plus petit type dans lequel elle rentrera (règles modulo sur signé vs non signé). Si vous êtes sur un système avecint
16 bits,#define count 70000
celacount
ressemblera à unlong
, comme s'il avait été défini commeconst long count = 70000;
. De plus, si vous passez l'une de ces versions decount
à une fonction attendueint
, tout compilateur sensé les traitera de la même manière.#define COUNT 70000
ci ne tronque pas en entier, mais le compilateur la traite comme un type suffisamment grand pour contenir ce nombre. Il est vrai que ce n'est pas évident quand vous utilisezCOUNT
que ce n'est pas un int, mais vous pouvezconst long
quand même dire la même chose à propos d'un .COUNT
de votre exemple est remplacée avant la compilation par l'expression70000
, dont le type est défini par les règles des littéraux, tout comme2
ou13L
ou4.0
sont définis par les règles des littéraux. Le fait que vous utilisez#define
pour alias ces expressions est sans importance. Vous pouvez utiliser#define
pour alias des morceaux arbitraires de code C, si vous le souhaitez.En tant que débutant de 2 semaines pour Arduino, je reprendrais l'idée générale qu'Arduino est occupé par des non-programmeurs. La plupart des croquis que j'ai examinés, y compris ceux du site Arduino, montrent un manque total d'ordre, avec des croquis qui ne fonctionnent pas et à peine un commentaire cohérent en vue. Les organigrammes sont inexistants et les "bibliothèques" sont un fouillis non modéré.
la source
Ma réponse est ... ils le font parce que ça marche. J'ai du mal à ne pas poser de question dans ma réponse telle que "pourquoi faut-il que ce soit" faux "?"
la source