#define выше static const int?

Я вижу много людей, а также библиотеки, определяющие константы (например, номера выводов, длину элементов и т. д.) как #define:

#define LENGTH 5

Хотя в этом случае рекомендуется использовать static const int:

static const int LENGTH = 5;

Я провел тест, и для памяти это не имеет значения.

Есть ли какая-то конкретная причина, по которой #define так часто (неправильно) используется в Arduino?

, 👍1

Обсуждение

Старые привычки из простого C?, @Edgar Bonet

@EdgarBonet Я уже немного «побаивался» такого замечания., @Michel Keijzers

Люди копируют примеры людей с вредными привычками или учатся у людей с вредными привычками., @Majenko

Я бы использовал байт для значений <= 255, экономя память., @CrossRoads

@CrossRoads Вы правы ... хотя я использую в основном int, когда просто хочу что-то протестировать, для программы, в которой я ожидаю (даже в будущем), что память является проблемой (что очень быстро для Arduino), я использую меньшие типы . В этом случае это не имеет значения, он не использует память SRAM., @Michel Keijzers


1 ответ


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

3

Для чисел, безусловно, предпочтительнее 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