Inttypes против определенных интегральных типов Arduino

В своих проектах Arduino я использую как типы Arduino, так и типы, определенные в файле «inttypes.h», который #includes stdint.h. До сих пор я всегда писал код только для микроконтроллера ATmega328P (либо на плате UNO, либо «отдельно»).

Для ясности, в этом вопросе я имею в виду следующие типы:

  • "Arduino": char, int, long; byte, word, unsigned long
  • inttypes: int8_t, int16_t, int32_t; uint8_t, uint16_t, uint32_t

  • Какова фактическая разница между, например, int и int16_t?
  • Всегда ли возможно неявное преобразование между соответствующими типами или его следует избегать, даже если компилятор не жалуется? (довольно часто в своих программах я передаю int16_t в качестве аргумента int функции, и это всегда работает, но вообще это хорошая практика?

, 👍3


2 ответа


Лучший ответ:

4
  • "Arduino": char, int, long; byte, word, unsigned long
  • inttypes: int8_t, int16_t, int32_t; uint8_t, uint16_t, uint32_t

Лучшей классификацией была бы следующая:

  • C и C++: char, int, long, unsigned long
  • "Arduino": байт, слово
  • inttypes: int8_t, int16_t, int32_t; uint8_t, uint16_t, uint32_t

Обычно я избегаю специфичных для Arduino типов, поскольку они нестандартны и обычно не существуют за пределами мира Arduino. Что касается другие типы, как предлагает Мишель Кейзерс, я использую типы C когда я не очень забочусь о точном размере. int гарантированно будет не менее 16 бит, но, вероятно, будет 32 бита в 32-битной архитектуре. Это хороший тип по умолчанию, так как он должен эффективно обрабатываться. на любой архитектуре. Эти типы позволяют вам писать переносимый код, который автоматически выбирает «правильную» целочисленную ширину для любого архитектуры, для которой он был скомпилирован.

Если вам важен точный размер, что часто в среде с ограниченной памятью используйте типы из inttypes.h. И делай не беспокойтесь о неявных преобразованиях: пока оба типа являются широкими достаточно для хранения чисел, которые вам нужно сохранить, преобразования типов, будь то неявный или явный, всегда сохраняет значение.

,

2

int может быть в зависимости от аппаратной архитектуры и в основном 16 или 32 бит. Однако int16_t всегда 16-битный, независимо от аппаратной архитектуры.

Что-то пойдет не так, если у вас 32-битная архитектура (для int) и вы собираетесь преобразовать ее в int16_t, тогда вы потеряете 16 бит MSB. Хотя я думаю, что в этом случае компилятор выдаст предупреждение (так что в вашем случае все в порядке, но это может помешать большому количеству работы, когда вы портируете свой код на 32-битную архитектуру).

Однако во всех Arduino int определен как 16-битный, за исключением плат на базе Due и SAMD, см.: справочник по Arduino для int (обновлено после комментария per1234 ниже, спасибо за это).

Обычно я использую целое число, когда меня не очень волнует тип (и я знаю, что оно останется ниже 32768, как и для большинства индексов в циклах). Но если вы определяете (большой) массив, лучше использовать явный тип, или если вы точно знаете, что значение никогда не будет выше 32768 (int8_t) или неотрицательно и 65535 (uint8_t).

Кроме того, для беззнакового символа "глаз" для беззнакового "целого" значения до 255 uint8_t выглядит лучше, чем "char", который больше похож на символ, чем на значение.

,

«Тем не менее, все Arduino имеют int, определенный как 16-битный, я думаю, что это верно даже для Due». Это неправильно. См. https://www.arduino.cc/en/Reference/Int., @per1234

@ per1234 Спасибо, я обновил свой ответ., @Michel Keijzers

«или если вы точно знаете, что значение никогда не будет выше 32768 (int8_t) или неотрицательно и 65535 (uint8_t)». Вы имели в виду int16_t и uint16_t? Эта тема может вызвать некоторую путаницу, а случайные ошибки, подобные этой, могут усугубить проблему., @S Walsh