Зачем использовать переменную int для булавки, когда const int, enum или #define имеет больше смысла

Почему люди используют переменную для указания номера штыря, когда штырь вряд ли изменится во время выполнения кода?

Много раз я вижу int для определения вывода,

int led = 13;

, когда использование const int

const int led = 13;

или enum , или #define

#define LED 13

имеет гораздо больше смысла.

Это даже в учебниках на сайте Arduino, например, в первом учебнике, которое большинство людей запускает, прочитайте где-нибудь что const int предпочтительнее #define. Почему это не поощряется с самого начала, а не позволяет людям развивать вредные привычки с самого начала? Я заметил это некоторое время назад, но в последнее время это начало раздражать меня, следовательно, вопрос.

Память /обработка /вычисление wise - это const int, enum или, если это важно, #define, лучше обычного int, т.е. занимает меньше памяти, хранящейся в различной памяти (Flash , EEPROM, SRAM), быстрее выполнять, быстрее компилировать?


Это может быть дубликат Лучше ли использовать #define или const int для констант? , но я обращаюсь к вопросу о том, почему люди используют переменные и как производительность улучшается, когда они этого не делают, а не какой тип константа лучше.

23 голоса | спросил Greenonline 14 AM000000100000003031 2015, 10:22:30

4 ответа


19
 const int led = 13;

Это правильный метод. Или даже:

 const byte led = 13;

Сколько у вас контактов?

В некоторых учебниках не так много контроля качества, как они могли бы быть.

Производительность будет лучше использовать const byte, сравните с int, однако компилятор может быть достаточно умным, чтобы понять, что вы делаете.

Что вы можете сделать, это мягко поощрять людей использовать более эффективные методы, используя их в своем собственном коде.


Ответы на комментарии

  1. Комментировщик предположил, что byte не является стандартным C. Это правильно, однако это сайт Arduino StackExchange, и я считаю, что использование стандартных типов, поставляемых с помощью Arduino IDE, приемлемо.

    В Arduino.h есть такая строка:

     typedef uint8_t byte;
    

    Обратите внимание, что это не совсем то же самое, что unsigned char. См. uint8_t vs unsigned char и Когда is uint8_t â ‰ unsigned char? .

  2. Другой комментатор предположил, что использование байта не обязательно улучшит производительность, потому что числа, меньшие, чем int, будут переведены на int (см. Правила целых рекламных кампаний, если вы хотите больше на это).

    Однако в контексте идентификатора const компилятор будет генерировать эффективный код в любом случае. Например, демонтаж «мигает» дает это в оригинальной форме:

     00000086 <loop & gt ;:
      86: 8d e0 ldi r24, 0x0D; 13
      88: 61 e0 ldi r22, 0x01; 1
      8a: 1b d1 rcall. + 566; 0x2c2 <digitalWrite>
    

    Фактически он генерирует один и тот же код: 13:

    • Литерал
    • Является #define
    • Является const int
    • Является const byte

Компилятор знает, когда он может поместить число в один регистр и когда он не может. Тем не менее, хорошая практика использует кодировку, указывающую на намерение . Создание кода const дает понять, что номер не изменится и сделает его byte (или uint8_t) дает понять, что вы ожидаете небольшое число.


Сбивание сообщений об ошибках

Еще одна важная причина избежать #define - это сообщения об ошибках, которые вы получаете, если ошибаетесь. Рассмотрим этот «мигающий» эскиз, который имеет ошибку:

 #define LED = 13;

void setup () {
  pinMode (LED, OUTPUT); //<---- строка с ошибкой
}

void loop () {
  digitalWrite (LED, HIGH); //<---- строка с ошибкой
  Задержка (1000);
  digitalWrite (LED, LOW); //<---- строка с ошибкой
  Задержка (1000);
}

Поверхность выглядит нормально, но генерирует эти сообщения об ошибках:

 Blink.ino: В функции â € ~void setup () â € ™:
Blink: 4: ошибка: ожидаемое первичное выражение перед â € ~ = â € ™ token
Blink: 4: ошибка: ожидаемое первичное выражение перед â € ~, â € ™ token
Blink: 4: ошибка: ожидается `; ' до â € œ ""
Blink.ino: В функции âvoid loop () â € ™:
Blink: 8: ошибка: ожидаемое первичное выражение перед â € ~ = â € ™ token
Blink: 8: ошибка: ожидаемое первичное выражение перед â € ~, â € ™ token
Blink: 8: error: expected `; ' до â € œ ""
Blink: 10: ошибка: ожидаемое первичное выражение перед â € ~ = â € ™ token
Blink: 10: ошибка: ожидаемое первичное выражение перед â € ~, токеном
Blink: 10: ошибка: ожидается `; ' до â € œ ""

Вы просматриваете первую выделенную строку (строка 4) и даже не видите символ "=". Кроме того, линия выглядит отлично. Теперь довольно очевидно, что проблема здесь (= 13 заменяется на LED)), но когда строка содержит 400 строк дальше в коде, это не очевидно, проблема связана с тем, как определяется светодиод.

Я видел, как люди падали много раз (включая меня).

ответил Nick Gammon 14 PM000000120000000331 2015, 12:03:03
18

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

Большая часть кода и учебных пособий Arduino написана людьми, которые никогда не занимались программированием и очень «самоучиваются» из ресурсов людьми, которые сами очень самоучительны, без надлежащей подготовки к программированию.

Многие из фрагментов кода учебника, который я вижу по всему месту (и особенно тех, которые доступны только в видеороликах YouTube --- urgh), были бы ошибкой, если бы я их маркировал на экзамене.

Да, a const предпочтительнее неконстантного и даже над #define, потому что:

  • A const (например, #define, в отличие от неконстантного) не выделяет никакой ОЗУ
  • A const (как не-const, но в отличие от #define) дает значение a type

Второй момент представляет особый интерес. Если специально не указано иное с внедренным типом ((long) 3) или суффиксом типа (3L) или наличием десятичной точки (3.0), #define всегда будет целым числом, и вся математика, выполняемая над этим значением, будет выглядеть так, как если бы она была целым числом. В большинстве случаев это не проблема, но вы можете столкнуться с интересными сценариями при попытке #define сохранить значение, которое больше, чем целое число, например #define COUNT 70000, а затем выполнить математическую операцию с другими значениями int. Используя const, вы можете сообщить компилятору «Это значение должно рассматриваться как этот тип переменной» - поэтому вместо этого вы должны использовать: const long count = 70000; и все будет работать так, как ожидалось.

Он также имеет эффект постукивания, который проверяет тип при передаче значения вокруг места. Попробуйте передать const long функцию, ожидающую int, и она будет жаловаться на сужение диапазона переменных (или даже полностью не скомпилировать в зависимости от сценария). Сделайте это с помощью #define, и он просто молча продолжит давать вам неправильные результаты и оставит вас царапать вашу голову часами.

ответил Majenko 14 PM000000120000002331 2015, 12:12:23
0

Мой ответ: они делают это, потому что это работает. Мне трудно задавать вопрос в моем ответе, например «почему это должно быть« неправильно »?»

ответил linhartr22 21 AM00000020000005031 2015, 02:18:50
0

Как двухнедельный новичок в Arduino, я бы взял общую идею о том, что Ардуино занимают не-программисты. Большинство эскизов, которые я рассмотрел, в том числе на сайте Arduino, показывают полное отсутствие порядка, с эскизами, которые не работают & едва заметный комментарий. Блок-схемы не существуют, а «Библиотеки» являются неуправляемыми беспорядками.

ответил Jim 11 Jpm1000000pmWed, 11 Jan 2017 15:36:17 +030017 2017, 15:36:17

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132