цикл for работает ненормально в Arduino

Рассмотрим следующий цикл в C:

int i;
for (i = 1; i > 0; i++);

После того, как i достигнет INT_MAX, он будет поворачиваться INT_MIN с приращением. Затем i > 0 оценивает false, и цикл for завершается.

Однако цикл for не завершается в Arduino, поскольку i > 0 сравнивает false, даже если i равно -32768.

Это почему?

PS. Я использую Mega 2560 с Arduino версии 1.0.5.
PPS. int действительно 16 бит на Mega 2560
PPPS. Полный эскиз ниже:

void setup () {
  int i;
  Serial.begin(9600);
  for (i = 1; i > 0; i++);
}

void loop () {
  Serial.println(100);
}

И я ничего не увижу в последовательном мониторе


person user3074306    schedule 28.05.2014    source источник
comment
Arduino постоянно зацикливается в функции loop (). Зачем использовать цикл For?   -  person Carlos Martins    schedule 28.05.2014
comment
Можете ли вы показать полный небольшой набросок, который воспроизводит проблему, включая то, как вы определяете, завершился ли цикл for?   -  person Patricia Shanahan    schedule 28.05.2014


Ответы (3)


Разборка функции настройки дает:

0000014a <setup>:
 14a:   80 e3           ldi r24, 0x30   ; 48
 14c:   94 e0           ldi r25, 0x04   ; 4
 14e:   40 e8           ldi r20, 0x80   ; 128
 150:   55 e2           ldi r21, 0x25   ; 37
 152:   60 e0           ldi r22, 0x00   ; 0
 154:   70 e0           ldi r23, 0x00   ; 0
 156:   42 d2           rcall   .+1156      ; 0x5dc <_ZN14HardwareSerial5beginEm>
 158:   ff cf           rjmp    .-2         ; 0x158 <setup+0xe>

так что теперь ясно: avr-gcc считает, что i > 0 в for(i = 1; i > 0; i++) никогда не будет оценивать false, и оптимизировал условие выхода.

person user3074306    schedule 29.05.2014

Скорее всего, int также 32-битный на Arduino. На выполнение 2 ^ 31 итераций нужно время. Вы можете изменить 'int' на 'short', и он должен завершиться, как ожидалось.

person Danke Xie    schedule 28.05.2014
comment
Э ... int 16-битный на Mega 2560 (но не на Due) ~ _ ~ - person user3074306; 28.05.2014
comment
Хорошо, вы можете использовать gcc -S ‹prog.c› для генерации кода сборки и проверки наличия ошибки. Это также могло быть связано с оптимизацией, которую вы можете отключить, добавив флаг -O0. Надеюсь, это поможет. - person Danke Xie; 28.05.2014

когда определено int, по умолчанию компилятор принимает его размер равным 16 битам.

Но когда вы увеличиваете его до 32767, т.е.

int i=32767;
i++;

Размер i автоматически увеличивается до 32 бит. Это потому, что размер не указан в декларации.

Это заставляет вашу программу не останавливаться на 32767.

Следовательно, если вы хотите остановить цикл for на 32767,

вы должны указать это как

short int i;

Если вы хотите проверить это, вы можете попробовать следующее

short int x;
for(x=1; x>0; x++)
{
  mySerial.println(x);
}

А ТАКЖЕ

int x;
for(x=1; x>0; x++)
{
  mySerial.println(x);
}
person Damon    schedule 28.05.2014