Что за цирк с типом данных int?

Всем привет. Я новичок. Делаю первые шаги. Сразу срывает крышу вот с такого кода:

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  while(!Serial);
}

void loop() {
  // put your main code here, to run repeatedly:
  Serial.println("Start");
  for (int i = 0; i <= 32767; i++){
    Serial.println(i);
  }
  Serial.println("End");
}

В окне монитора COM-порта счетчик переменной i благополучно доходит до порога 32767, проскакивает дальше, и летит в космос:

Во-первых, почему не срабатывает условие ограничения цикла?
Во-вторых, почему не срабатывает длина значения счетчика цикла i? В документации сказано, что в int влезают целые числа от -32767 до +32767 с 0 посередине. Тут же на скриншоте видно, что значение счетчика явно больше +32767. Что за цирк?!

При условии, что int == int16_t, т.е. 16-битный тип. Но, скажем, на esp8266 и esp32 int - 32-битный тип, соответственно, и пределы другие. Вы на каком МК все это запускаете?

При int16_t такая же фигня.

А как оно должно сработать ? После 32767 будет -32768 и оно то же в рамках условия …

И сразу вот так прям

Запомните самый ценный совет, который Вы можете сейчас получить.

Если Вы наблюдаете цирк с типом данных, с оператором языка, выполнение условий, всегда твёрдо знайте: цирк не с типом данных, не с оператором языка, не с выполнением условий - цирк всегда с Вашей головой!

Это верно всегда! Совсем всегда! Абсолютно всегда! Без каких бы то ни было исключений.

Запомните это, и всегда из этого исходите. Никогда не пытайтесь доказать компилятору или процессору, что Вы правы Вы, а он - нет. Это избавит Вас от большого количества мата и возмущённых постов. Станет гораздо легче жить и многому научитесь.

Теперь по поводу Вашего цирка.

Оператор

for (<d1>; <d2>; <d4>) <d3>;

работает так:

  1. Выполняет действие d1
  2. Выполняется действие d2
  3. если результат d2 оказался нулём, ВЫХОД ИЗ ЦИКЛА
  4. выполняется действие d3
  5. выполняется действие d4
  6. переход к пункту 2

Обратите внимание, что d4 исполняется до новой проверки d2. В Вашем случае d4 - это i++. Число 32767 удовлетворяет условию. А сколько будет 32767+1 ? Знаете?

Дальше думайте сами.

3 лайка

А почему в Serial выводятся числа больше 32767?

1 лайк

Скорее всего код у автора не тот, что показан

С моего сообщения в вуки тоже самое и при типе int16_t.

А если условие поставить строго меньше вместо меньше равно?

Тогда работает.

Интересно… Даже если Сериал принт на печати интерпретирует переменную как лонг, числа более 65к вроде уходить не должны.

Прогонял, число растёт выше.

Не знаю

Пробовал не на железе, а на wokwi.

Так я и думал… Долго думал, пытаясь понять, каким образом выводимые в COM-порт значения 1584680 соотносятся с типом данных int, который вроде как имеет длину два байта, и следовательно либо вмещает в себя значения от -32к до +32к, либо от 0 до +64к. Но уж никак не может в себя вмещать значение 1 584 680. Вы скриншот видели? Заметьте - я стал заниматься Ардуино в 2023-м году. Википедия говорит, что Ардуино родилась в далеком 2000-м году. Не льщу себя надеждой, что я прям такой особенный, и за 23 года жизни платформы этот глюк именно на мне проявился первым. Ну и насчет новичка. Это я в Ардуино новичок… А на VB если счетчик, отсчитав от 0 до 32к, не остановит цикл, а пойдет дальше и загонит цикл в бесконечность, то такой цикл сочтут бредом сивой кобылы.

Евгений Петрович ответил Вам на Ваш первый вопрос.

Евгений Петрович не ответил мне на вопрос, как в 2 байта (16 бит) можно уместить число 1584680, что в двоичной системе равно 110000010111000101000, и занимает для хранения 21 бит.

Вам же расписали работу вашего цикла, и почему он не останавливается. Хотите, чтобы останавливался - замените <= на <, иначе он так и будет крутиться в бесконечном цикле. И это будет бредом не сивой кобылы, а автора кода
Что касается размерности, то тут скорее всего дело в реализации сериала

1 лайк

Я бы с вами с огромным удовольствием согласился, но код сей я взял из официального гайда на Ардуино. Я не думаю, что разработчики платформы с 23-м стажем разместили в учебнике код, который работает не так, как написано. См. скриншот.

Сделал так, как вы рекомендуете. Теперь компилятор стал ругаться:

Друзья, если код из учебника бракованный, дайте пожалуйста образец правильно работающего кода. Пожалуйста.