#define выше static const int?
Я вижу много людей, а также библиотеки, определяющие константы (например, номера выводов, длину элементов и т. д.) как #define:
#define LENGTH 5
Хотя в этом случае рекомендуется использовать static const int:
static const int LENGTH = 5;
Я провел тест, и для памяти это не имеет значения.
Есть ли какая-то конкретная причина, по которой #define так часто (неправильно) используется в Arduino?
@Michel Keijzers, 👍1
Обсуждение1 ответ
Лучший ответ:
Для чисел, безусловно, предпочтительнее const <type>
. В основном это связано с тем, что он навязывает тип (который был бы необязательным только для #define
), который может иметь косвенный эффект для математики.
Это не означает, что вы всегда должны использовать const <type>
вместо #define
. #define
имеет свое место.
Одним из преимуществ #define
по сравнению с const <type>
является то, что это прямая замена буквального текста. Замена выполняется перед компиляцией, поэтому все, допустимое в вашем коде, может быть помещено в #define
, в то время как только то, что оценивается как правильный тип во время выполнения, может помещаться в const <type>
.
Возьмем, к примеру, строки. Да, вы можете использовать:
const char *foo = "This is text";
И вы можете использовать это везде, где ожидается const char *
. Однако, если вы используете:
#define FOO "This is text"
вы можете использовать его везде, где ожидается строковый литерал. Это делает полезными такие вещи, как способ C конкатенации строковых литералов во время компиляции:
Serial.println("I say: " FOO);
Два строковых литерала "Я говорю: "
и FOO
(который расширяется до "Это текст"
) объединяются в один строковый литерал во время компиляции в:
Serial.println("I say: This is text");
Вы не можете сделать это с помощью const char *
.
Еще одно большое отличие const <type>
от #define
заключается в при оценке выражений. Возьмем, к примеру:
const float sinpi = sinf(3.141592653);
Это будет вычислять синус PI один раз при запуске. Однако:
#define SINPI sinf(3.141592653);
будет вычислять синус PI каждый раз, когда он используется.
Таким образом, в данном случае const float
не только дает вам заданный тип float
для всех вычислений, но и снижает накладные расходы за счет однократного запуска вычисления и сохранения результат.
Как видите, у каждого есть свои плюсы и минусы. А вообще по цифрам:
const <type>
предпочтительнее для хранения внутренних числовых данных, которые не изменяются, и#define
чаще всего используется для данных, настраиваемых пользователем, поскольку он не навязывает;
в конце строки, который часто забывают (более новые ) пользователи.
Спасибо за понимание ... последнее замечание «интересно» (забыто новыми пользователями)., @Michel Keijzers
хотя это не имеет прямого отношения к теме вопроса, возможно, вы могли бы упомянуть использование #define для условной компиляции, @jsotola
- Зачем использовать переменную int для вывода, когда const int, enum или #define имеют гораздо больше смысла
- Считается ли #ifdef __SD_H__ плохой практикой?
- Синтаксис двоичных констант
- Создание массива с длиной, полученной из библиотеки
- Ошибка сегментации и огромная потребность в SRAM для Serial.println
- Как связать процессор компьютера с Arduino на плате?
- Как объявить массив переменного размера (глобально)
- Программирование Arduino с использованием Python, а не C/C ++
Старые привычки из простого C?, @Edgar Bonet
@EdgarBonet Я уже немного «побаивался» такого замечания., @Michel Keijzers
Люди копируют примеры людей с вредными привычками или учатся у людей с вредными привычками., @Majenko
Я бы использовал байт для значений <= 255, экономя память., @CrossRoads
@CrossRoads Вы правы ... хотя я использую в основном int, когда просто хочу что-то протестировать, для программы, в которой я ожидаю (даже в будущем), что память является проблемой (что очень быстро для Arduino), я использую меньшие типы . В этом случае это не имеет значения, он не использует память SRAM., @Michel Keijzers