Pourquoi int est-il seulement 2 octets?

9

Lorsque vous utilisez C / C ++ sur d'autres plates-formes, le inttype est généralement de 4 octets (ou potentiellement plus). Cependant, sur Arduino, ce n'est que 2 octets.

Pourquoi est-ce différent? Cela affecte-t-il les performances si j'utilise toujours les 4 octets à la longplace?

Peter Bloomfield
la source
2
notez que intc'est 4 octets sur l'Arduino Due. A shortsera de 2 octets sur tous les Ardunios existants, mais j'insiste sur les conseils des autres à utiliser int16_tou uint16_t.
Ron

Réponses:

10

L'ATmega328 utilisé dans de nombreux Arduinos est un microcontrôleur 8 bits. Cela signifie que les registres sont de 8 bits, le bus de données est de 8 bits, les ports sont de 8 bits. Il y a quelques aspects minimes sur 16 bits dans le système (par exemple l'un des temporisateurs), mais presque tout est sur 8 bits.

Par conséquent, la plupart des opérations gèrent 8 bits à la fois. Travailler sur n'importe quoi sauf 8 bits (c'est-à-dire des entiers 16 bits ou 32 bits et des nombres à virgule flottante) nécessite ce qui pourrait être essentiellement décrit comme une émulation logicielle, où le compilateur utilise plusieurs instructions pour travailler sur ces variables plus grandes.

8 bits est évidemment suffisant pour adresser un port 8 bits. Il suffit également de gérer de nombreux compteurs de boucles, valeurs de retour et caractères ASCII. Ce n'est pas vraiment suffisant quand il s'agit de chiffres. Un entier 8 bits signé (int8_t) ne peut représenter que -128 -> +127. Non signé (uint8_t) ne peut représenter que 0 -> 255.

Les entiers 8 bits sont assez limitatifs. C / C ++ int doit représenter au moins -32 678 -> + 32 767 donc correspond à int16_t - la plus petite taille qui le fera. Cela donne un bon équilibre de portée et d'efficacité. Ceci est particulièrement important lorsque les débutants apprennent - le débordement n'est pas vraiment quelque chose que les non-programmeurs comprennent.

Cela a cependant un impact sur les performances, car la plupart des opérations 16 bits prennent au moins deux fois plus de temps qu'une opération 8 bits et utilisent deux fois plus de registres. Cela peut ou non faire une différence pour vous.

Beaucoup d'entre nous passent aux types natifs tels que int8_t et uint8_t car cela vous donne beaucoup plus de contrôle.

Cybergibbons
la source
3
Juste une note: ce n'est pas l'équipe Arduino qui a mappé int à int16_t, "int" est un mot clé réservé C / C ++, et le mappage de type fait partie de l'ABI ( gcc.gnu.org/wiki/avr-gcc ) que le Les développeurs du compilateur avr-gcc ont décidé de suivre. Une autre différence notable est dans le type "double" qui est généralement de 64 bits de large, tandis que dans le avr-gcc est de 32 bits comme "float"
cmaglie
Merci. Je ne sais pas pourquoi j'ai écrit ça. Je sais que l'int doit représenter 32 678 -> + 32 767 (bien que, en fait, je pense qu'il y avait un compilateur propriétaire pour l'un des processeurs NEC qui n'a pas suivi cela). Je pense que c'est parce que je n'aime pas cacher les largeurs sur les systèmes embarqués - utiliser int16_t est beaucoup plus clair.
Cybergibbons
1
+1 pour l'utilisation de types natifs clairs! Sur l'Arduino Due, un intest 32 bits! arduino.cc/en/Reference/int
Ron
3

Un fait important concernant les langages C et C ++ est que leurs normes respectives ne définissent pas la taille (en octets) des types de nombres entiers et à virgule flottante.

Ils définissent simplement des plages minimales et la relation entre ces plages, par exemple

range(short) <= range(int) < range(long)

Ainsi, la taille, par exemple, d'un intdépendra généralement de:

  • la plate-forme cible (processeur)
  • le compilateur lui-même
jfpoilpret
la source
dites-vous que sizeof(short) == sizeof(int) == sizeof(long)c'est possible?
Ron
@ ron-e Théoriquement, oui, ce serait possible. En pratique, cependant, je n'ai jamais vu cela. Dans la plupart des compilateurs / plates-formes, on pourrait s'y attendre (bien que cela ne soit pas imposé) sizeof(short) < sizeof(long).
jfpoilpret