Каков наилучший способ определить вывод ввода / вывода?

9

Я читаю определения как

const int ledPin = 9;

а также

#define ledPin 9

Я знаю, что определение как

int ledPin = 9;

Это плохая практика, если вы не собираетесь ее менять (что обычно не происходит), хотя я видел это несколько раз в программах Arduino. Какой из двух других предпочтительнее?

Йорис Гроусман
источник

Ответы:

6

#define ledPin 9является предпочтительным. Делая это, int ledPin = 9;вы будете выделять intпамять, значение которой используется каждый раз, когда вы используете ledPin. #defineотличается в том смысле, что не выделяет память. нет памяти называется ledPin. Перед компиляцией все «ledPin» в коде (кроме строк) заменяются на 9. Так в основном

digitalWrite(ledPin);

становится

digitalWrite(9);

Преимущества #define: экономит память и, поскольку все ledPinзаменяются 9 до выполнения , экономит процессорное время.

Не имеет большого значения в маленьких кодах ...


источник
Действительно ли встроенные компиляторы настолько плохи, что не используют постоянное свертывание при использовании const int?
Чуу
1
@ Chuu Насколько я знаю, Arduino использует GCC для AVR. Так что это почти наверняка должно быть оптимизировано. Ответы здесь не показывают глубокого понимания хорошей практики в C ++
chbaker0
3
в C ++ const int ledPin = 9;предпочтительнее 2 других вариантов. Это НЕ будет выделять память для intисключения, если вы где-то определите указатель на него, что никто не сделает.
jfpoilpret
Const int выделяет память @jfpoilpret. #define не занимает никакой памяти, потому что это просто символическое имя выражения, а не имя памяти ...
Проверьте эту ссылку cplusplus.com/forum/beginner/28089 и убедитесь сами. В противном случае просто выполните проверку в Arduino IDE: проверьте размер данных с помощью const и с помощью #define.
jfpoilpret
4

Строго говоря, #defineподход будет использовать немного меньше памяти. Разница обычно крошечная, хотя. Если вам нужно уменьшить использование памяти, то другие оптимизации, вероятно, будут гораздо более эффективными.

Аргумент в пользу использования const int- безопасность типов . Где бы вы ни ссылались на этот пин-код по переменной, вы точно знаете, какой тип данных вы получаете. Он может быть продвинут / преобразован неявно или явно кодом, который его использует, но он должен вести себя очень четко.

Напротив, значение в a #defineоткрыто для интерпретации. В большинстве случаев это, вероятно, не вызовет у вас никаких проблем. Вам просто нужно быть немного осторожнее, если у вас есть код, который делает предположения о типе или размере значения.

Лично я почти всегда предпочитаю безопасность типов, если у меня нет очень серьезной необходимости экономить память.

Питер Блумфилд
источник
Я был в лагере #define, пока не прочитал ответ Питера. Думаю, я знаю, кто будет рефакторинг кода в эти выходные. ;)
linhartr22
2

Вероятно, лучшим способом было бы
const uint8_t LED_PIN = 9; // may require to #include <stdint.h>
или
const byte LED_PIN = 9; // with no include necessary
const unsigned char LED_PIN = 9; // similarly
Имя указано заглавными буквами в соответствии с общей практикой в ​​C ++ (и других) для именования констант. Это не должно использовать какую-либо оперативную память само по себе, и использовать около 1 байта программной памяти на использование.
Однако могут возникнуть проблемы, когда число превышает 127 и увеличивается в знаке при переходе на более крупные целые числа со знаком (не совсем уверен в этом), хотя это вряд ли произойдет с номерами выводов.

rykien
источник
-1

Не только будет

const int ledPin = 9;

занимают ОЗУ, но в этом случае будет использовать больше ОЗУ, чем необходимо, так как digitalWrite(uint8_t, uint8_t)нужны только однобайтовые аргументы, а int обычно составляет два байта (зависит от компилятора, но типично). Обратите внимание, что вы можете дать литералу явный тип в #define:

#define ledPin ((int)9) 

хотя в контексте, таком как аргумент функции, где требуется конкретный тип (потому что функция была правильно прототипирована!), он либо будет неявно приведен, либо получит сообщение об ошибке, если типы не совпадают.

JRobert
источник
@DrivebyDownvoter, не могли бы вы прокомментировать свои причины?
JRobert