Quelle est la meilleure façon de définir une broche d'E / S?

9

Je lis des définitions comme

const int ledPin = 9;

et aussi

#define ledPin 9

Je sais qu'une définition comme

int ledPin = 9;

est une mauvaise pratique si vous ne le changez pas (ce que vous ne ferez généralement pas), bien que je l'ai vu plusieurs fois dans les programmes Arduino. Lequel des deux autres est préféré?

Joris Groosman
la source

Réponses:

6

#define ledPin 9est préféré. Ce faisant, int ledPin = 9;vous allouerez une intmémoire dont la valeur est utilisée à chaque utilisation ledPin. #defineest différent dans le sens où il n'alloue pas de mémoire. il n'y a pas de mémoire appelée ledPin. Avant de compiler tous les "ledPin" dans le code (autres que les chaînes) sont remplacés par 9. Donc en gros

digitalWrite(ledPin);

devient

digitalWrite(9);

Avantages de #define: économise de la mémoire et comme tous ledPinsont remplacés par 9 avant l'exécution , cela fait gagner du temps au processeur.

Peu importe vraiment dans les petits codes ...


la source
Les compilateurs intégrés sont-ils vraiment si mauvais qu'ils ne font pas de pliage constant lors de l'utilisation const int?
Chuu
1
@chuu pour autant que je sache, Arduino utilise gcc pour avr. Il devrait donc certainement être optimisé. Les réponses ici ne montrent pas beaucoup de compréhension des bonnes pratiques en C ++
chbaker0
3
en C ++, const int ledPin = 9;est préféré à 2 autres options. Cela n'allouera PAS de mémoire pour un intsauf si vous lui définissez un pointeur quelque part, ce que personne ne ferait.
jfpoilpret
Const int alloue de la mémoire @jfpoilpret. #define ne prend pas de mémoire car c'est juste le nom symbolique d'une expression et non le nom d'une mémoire ...
Consultez ce lien cplusplus.com/forum/beginner/28089 et voyez par vous-même. Sinon, effectuez simplement la vérification avec Arduino IDE: vérifiez la taille des données avec const et avec #define.
jfpoilpret
4

À strictement parler, l' #defineapproche utilisera un peu moins de mémoire. Cependant, la différence est généralement minime. Si vous devez réduire l'utilisation de la mémoire, d'autres optimisations seraient probablement beaucoup plus efficaces.

Un argument en faveur de l'utilisation const intest la sécurité des types . Partout où vous faites référence à ce numéro d'identification par variable, vous savez exactement quel type de données vous obtenez. Il peut être promu / converti implicitement ou explicitement par le code qui l'utilise, mais il doit se comporter de manière très claire.

En revanche, la valeur de a #defineest sujette à interprétation. La grande majorité du temps, cela ne vous posera probablement aucun problème. Vous avez juste besoin d'être un peu prudent si vous avez du code qui fait des hypothèses sur le type ou la taille de la valeur.

Personnellement, je préfère presque toujours la sécurité de type, sauf si j'ai un besoin très sérieux d'économiser de la mémoire.

Peter Bloomfield
la source
J'étais dans le camp #define jusqu'à ce que je lise la réponse de Peter. Je suppose que je sais qui refactorisera le code ce week-end. ;)
linhartr22
2

La meilleure façon serait probablement
const uint8_t LED_PIN = 9; // may require to #include <stdint.h>
ou
const byte LED_PIN = 9; // with no include necessary
const unsigned char LED_PIN = 9; // similarly
Le nom est en majuscules selon la pratique générale en C ++ (et autres) pour nommer les constantes. Cela ne devrait pas utiliser de RAM en soi et utiliser environ 1 octet de mémoire de programme par utilisation.
Cependant, il peut y avoir des problèmes lorsque le nombre est supérieur à 127 et est étendu aux signes tout en étant promu en entiers signés plus grands (pas tout à fait sûr à ce sujet), bien que cela ne se produise probablement pas avec les numéros de broche.

Rykien
la source
-1

Non seulement

const int ledPin = 9;

prendre de la RAM, mais dans ce cas, utiliser plus de RAM que nécessaire car il digitalWrite(uint8_t, uint8_t)n'a besoin que d'arguments d'un octet, et un int est généralement de deux octets (dépendant du compilateur, mais typique). Notez que vous pouvez donner au littéral un type explicite dans #define:

#define ledPin ((int)9) 

bien que dans un contexte tel qu'un argument de fonction où un type spécifique est requis (car la fonction a été correctement prototypée!), il serait implicitement converti ou obtiendrait un message d'erreur si les types ne correspondent pas.

JRobert
la source
@DrivebyDownvoter, pourriez-vous commenter vos raisons?
JRobert