Как правильно написать цикл for для обратного отсчета?

dbv1991
Offline
Зарегистрирован: 07.11.2016

for(i = 0; i <= 6; i++) 

Помогите, пожалуйста, как правильно записать цикл for чтобы он отсчитывал от числа, которое будет получено в процессе исполнения кода ( в данном примере вместо цифры 6)?

Спасибо!

 

 

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Объявить переменную, которой присваивать значение по ходу выполнения программы. Потом в цикле for вместо числа писать имя переменной.

int Number = 6; // начальное значение, можно инициализировать нулём.

void setup() 
{
  // какой-то код
}


void loop() 
{
  // какой-то код, где меняется и присваивается значение переменной Number

  for (int i=0; i <= Number; i++){
    // какой-то код     
  }
}

 

dbv1991
Offline
Зарегистрирован: 07.11.2016

Вот я подсчитал число нажатий на кнопку (назовем clicks), далее я нажимаю на другую кнопку и начинается обратный отсчет for( clicks; clicks=0, clicks--), так? У меня не запускается..

dbv1991
Offline
Зарегистрирован: 07.11.2016

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

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

dbv1991 пишет:

Вот я подсчитал число нажатий на кнопку (назовем clicks), далее я нажимаю на другую кнопку и начинается обратный отсчет for( clicks; clicks=0, clicks--), так? У меня не запускается..

Нет, не так. Я выше привёл пример.

dbv1991 пишет:

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

Цикл автоматически завершается после того, как логическое значение условия становится ложным.

dbv1991
Offline
Зарегистрирован: 07.11.2016

Вчитался, но чтобы, допустим, от 6 до 0 отсчитывало и останавливалось, как надо записать for(int i=o;  i<=6; 6--)?

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Без разницы, как считать: от 0 до 6 или от 6 до 0. Цикл будет выполняться одинаково.

for (int i=0; i < 6; i++) {}

for (int i=6; i > 0; i--) {}

Обратите внимание, что при  i <= 6 цикл выполнится 7 раз, а не 6. Чтобы выполнился 6 раз, надо  i < 6 или  i <= 5

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

dbv1991 пишет:

.... 6--

Как Вы себе это представляете? Шестёрка уменьшится на 1 и станет пятёркой? 

Это сильно, конечно,  - конструкция для настоящих мужчин, но в этом языке так в лоб не делается. Язык-то большей частью для девочек :)

Mr.Privet
Mr.Privet аватар
Offline
Зарегистрирован: 17.11.2015

Если у Вас есть переменная вне цыкла For и Вы ее хотите использовать в качестве агрумета в For то ее и создавать не нужно просто оставляете пустым. 02 Логичнее же ( в плане читаемости скетча ) использовать цыкл While, хотя результат у них один и тот же

int clicks = 0;
void setup() {
  Serial.begin(9600);
}
void loop() {
 clicks = 13;
 for (;clicks>0;clicks--)
 {
   delay(1000);
   Serial.println(clicks);
 }
  clicks=13;
  while(clicks>0)
  {
   delay(1000);
   Serial.println(clicks);
   clicks--;
  }
}

 

5N62V
Offline
Зарегистрирован: 25.02.2016

Дабы не плодить тем, напишу тут.

Читаю Харви и Пола Дейтел "Как программировать на С".  Все примеры они пишут типа :

#define SIZE 10

for(i = 0; i<=SIZE-1; i++){........}

Почему именно так: <=SIZE-1? А то я всю дорогу пишу <SIZE, но уже , блин, не один раз обжегся на том, что вроде бы очевидные для меня вещи на самом деле оказываются не тем, что я о них представлял. :)

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

5N62V пишет:

Дабы не плодить тем, напишу тут.

Читаю Харви и Пола Дейтел "Как программировать на С".  Все примеры они пишут типа :

#define SIZE 10

for(i = 0; i<=SIZE-1; i++){........}

Почему именно так: <=SIZE-1? А то я всю дорогу пишу <SIZE, но уже , блин, не один раз обжегся на том, что вроде бы очевидные для меня вещи на самом деле оказываются не тем, что я о них представлял. :)

Разницы между

for(int i=0;i<SIZE;i++)

и

for(int i=0;i<=SIZE-1;i++)

Нет никакой, дело вкуса, бо для нормального современного оптимизатора машинный код этих двух конструкций будет идентичен.

5N62V
Offline
Зарегистрирован: 25.02.2016

DIYMan пишет:

Нет никакой, дело вкуса, бо для нормального современного оптимизатора машинный код этих двух конструкций будет идентичен.

Ок, спасибо за ответ. Я это и предполагал, но подумалось, а вдруг есть какие-то подводные  камни в этом исскустве тыкать пальцАми в клавиатуру. :)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Если вы ловите подводные камни,то

#define SIZE 10
for(int i = 0; i<=SIZE-1; i++){........}//<-- обратите на int

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

qwone пишет:

Если вы ловите подводные камни,то

#define SIZE 10
for(int i = 0; i<=SIZE-1; i++){........}//<-- обратите на int

И? Где камни-то?

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Ну, может человеку нравится для красоты использовать двухсимвольные операции сравнения : == , <= , >=

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Разница действительно есть, и при определённых условиях она может проявиться.

Это пережиток С’онизма, а именно – одна из жоп оператора #define, за что его страшно не любят тру плюс-плюс-оиды и прочие сторонники «систематического» и «безошибочного» программирования к коим, по всей видимости, относятся и авторы книги.

Смотрите, допустим, мы используем #define для того, чтобы задать количество неких объектов. По смыслу задачи таковых объектов у нас не может быть больше, чем 256. Ну, а поскольку нумеруем мы их, как все нормальные люди, с нулевого, то при переборе всех объектов, для индекса можем выбрать переменную типа uint8_t.

Тогда конструкция

#define  AMOUNT  156

......

for (uint8_t i = 0; i < AMOUNT; i++) { ... }

будет нормально работать для любого количества объектов, кроме 256, т.е. наша i всегда заведомо меньше, чем 256.

А конструкция

#define  AMOUNT  256

......

for (uint8_t i = 0; i <= AMOUNT-1; i++) { ... }

Будет работать и при 256 тоже.

Почему я говорю, о «жопе #define»? Если бы вместо #define использовали бы типизированную константу, проблем бы не было.

5N62V
Offline
Зарегистрирован: 25.02.2016

qwone пишет:

for(int i = 0; i<=SIZE-1; i++){........}//<-- обратите на int

Вы имеете ввиду, что с точки зрения оптимизации и переносимости стоит писать

#define SIZE 10;


#if (SIZE<256)
       for( unsigned char i = 0; i<SIZE; i++) 
#elif  (SIZE>256 && SIZE< 65535)
       for( unsigned int i = 0; i<SIZE; i++)
#else
       for( unsigned long i = 0; i<SIZE; i++)
#endif
{.............}

 

sadman41
Онлайн
Зарегистрирован: 19.10.2016

ЕвгенийП пишет:

Почему я говорю, о «жопе #define»? Если бы вместо #define использовали бы типизированную константу, проблем бы не было.

Мне идея с переходом тоже в голову пришла, и я не бездействовал, а сразу нажал на капу...  попробовал на этом и успокоился - в обоих случаях мотает без остановки:

#define SIZE 256
void setup() {
  Serial.begin(9600);
   for (uint8_t i = 0; i <= SIZE-1; i++) {
//   for (uint8_t i = 0; i < SIZE; i++) {
    Serial.println(i);
  }
}

Какой пример правильный для наблюдения правильного поведения?

UPD

Но компилятор действительно бормочет:

sketch_feb03a.ino:5:26: warning: comparison is always true due to limited range of data type [-Wtype-limits]
 
    for (uint8_t i = 0; i < SIZE; i++) {
 
DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

ЕвгенийП пишет:

Разница действительно есть

Ну вы же понимаете, что дурак может и стеклянный хрен сломать, правда? Да и компиляторы нынче умные - и сразу расскажут, кто тут олень и почему переполнение или сравнение знакового с беззнаковым юзается. Правда вот, что по умолчанию в настройках IDE эти предупреждения "заботливо" отключены...

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

5N62V пишет:
Вы имеете ввиду, что с точки зрения оптимизации и переносимости стоит писать
  Так как мы программируем не напрямую , а через компилятор оптимизатор, то надо учитывать некий момент.

int i;
{
  /*работаем с переменной i */
}

 И

{
  int i;
  /*работаем с переменной i */
}

Так во втором коде памяти расходуется меньше, разумеется оперативной. А так же второй код идет без инкапсуляции. :)  хотя вроде переменная и присутсвует.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

qwone пишет:

5N62V пишет:
Вы имеете ввиду, что с точки зрения оптимизации и переносимости стоит писать
  Так как мы программируем не напрямую , а через компилятор оптимизатор, то надо учитывать некий момент.

int i;
{
  /*работаем с переменной i */
}

 И

{
  int i;
  /*работаем с переменной i */
}

Так во втором коде памяти расходуется меньше, разумеется оперативной. А так же второй код идет без инкапсуляции. :)  хотя вроде переменная и присутсвует.

Винни, выдыхай - речь шла не о том, где объявлена переменная цикла, а об условии сравнения - перечитай внимательно стартовый пост на эту тему ;)

sadman41
Онлайн
Зарегистрирован: 19.10.2016

Винни докурил главу про классы и перешел на другое... 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Короче - #define может как помочь, так и сделать великое, ужасное, чудовищное зло. Так же, как кухонный ножик - им можно резать салатик, а можно - соседа Васю за его пение невпопад, а в особенности за то, что эта сволочь сфальшивила, и вместо Си второй октавы спела Си-бемоль. 

5N62V
Offline
Зарегистрирован: 25.02.2016

DIYMan пишет:

Винни, выдыхай - речь шла не о том, где объявлена переменная цикла, а об условии сравнения - перечитай внимательно стартовый пост на эту тему ;)

Да любые нюансы интересны! ;)

qwone пишет:

 во втором коде памяти расходуется меньше, разумеется оперативной. А так же второй код идет без инкапсуляции. :)  хотя вроде переменная и присутсвует.

да, я почти понял. Если все это происходит в лупе, то меньше оперативки тратится за счет чего? За счет более короткого периода жизни i, если она объявлена внутри цикла?

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

5N62V пишет:

 За счет более короткого периода жизни i, если она объявлена внутри цикла?

Именно, т.к. в этом случае область видимости переменной ограничена телом цикла, и при выходе из цикла она того - тю-тю.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

DIYMan, если вы об этом.

dbv1991 пишет:

for(i = 0; i <= 6; i++) 

Помогите, пожалуйста, как правильно записать цикл for чтобы он отсчитывал от числа, которое будет получено в процессе исполнения кода ( в данном примере вместо цифры 6)?

Спасибо!

То я говорю что for(int i = 0; i <= 6; i++)  , int тут потерян

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

qwone пишет:

DIYMan, если вы об этом.

dbv1991 пишет:

for(i = 0; i <= 6; i++) 

Помогите, пожалуйста, как правильно записать цикл for чтобы он отсчитывал от числа, которое будет получено в процессе исполнения кода ( в данном примере вместо цифры 6)?

Спасибо!

То я говорю что for(int i = 0; i <= 6; i++)  , int тут потерян

Винни, не кури сегодня больше - это просто абстрактный пример, из книжки. Ничего там не потеряно, т.к. объявлено на предыдущей странице книжки, всё норм, не волнуйся - мы никого не потеряли. Вопрос был не про это ;) К тому же - ты процитировал не то сообщение, интересующее нас начало - в сообщении номер 9.

5N62V
Offline
Зарегистрирован: 25.02.2016

DIYMan пишет:

Именно, т.к. в этом случае область видимости переменной ограничена телом цикла, и при выходе из цикла она того - тю-тю.

Ох и безграмотные эти чувачки, братья Дейтел :))

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

5N62V пишет:
да, я почти понял. Если все это происходит в лупе, то меньше оперативки тратится за счет чего? За счет более короткого периода жизни i, если она объявлена внутри цикла?
Почитайте про основной капитал и оборотный капитал. Чем чаще у вас оборачиваются деньги, тем больше прибыль и больше у вас ежемесячный доход. Так и с переменными. Чем для больших дел у вас используются одни и те же регистры ОЗУ, тем больше вы можете организовать задач на одной и той же Ардуине.

sadman41
Онлайн
Зарегистрирован: 19.10.2016

А если переменные инициализировать в каждом блоке - они не износятся раньше времени? А то я переживаю...

5N62V
Offline
Зарегистрирован: 25.02.2016

qwone пишет:

 Почитайте про основной капитал и оборотный капитал

ну нифига себе новый уровень абстракции :)))

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

5N62V пишет:

Ох и безграмотные эти чувачки, братья Дейтел :))

Я в своё время читал трупа страуса и Майерса, Кента Бека ещё, про экстремальное программирование - зашла книжка, Герба Саттера, ну и, конечно, Герберта Шилдта. Братья Дейтелы как-то обошли меня стороной :)

sadman41
Онлайн
Зарегистрирован: 19.10.2016

5N62V пишет:

 Почитайте про основной капитал и оборотный капитал

Я понял - ему в библиотеке после Кернигана и Ритчи выдали Карла и Маркса. 

А братья безграмотные - это верно. Int используют для счета до 10 ;))

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

А если переменные инициализировать в каждом блоке - они не износятся раньше времени? А то я переживаю...

Истираются, но только с боков, и только - по нечётным дням недели. А в шаббат вообще - каждая третья не инициализируется.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

5N62V пишет:
Ох и безграмотные эти чувачки, братья Дейтел :))
А вот здесь самое интересное. У больших компьютеров память для программ и память для переменных это одно большое ОЗУ. И память переменных там за счет памяти экономить не надо. Так что когда объявлять переменные не сильно важно. не критично.

5N62V
Offline
Зарегистрирован: 25.02.2016

DIYMan пишет:

Короче - #define может как помочь, так и сделать великое, ужасное, чудовищное зло. Так же, как кухонный ножик - им можно резать салатик, а можно - соседа Васю за его пение невпопад, а в особенности за то, что эта сволочь сфальшивила, и вместо Си второй октавы спела Си-бемоль. 

Сосед Вася может быть импровизировал в стиле джаз, а Вы его ножичком..... 

Иван_123
Offline
Зарегистрирован: 17.01.2018

А какие книги посоветуете для (далее следует очень нелюбимое форумчанами слово) новичка? 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Иван_123 пишет:

А какие книги посоветуете для (далее следует очень нелюбимое форумчанами слово) новичка? 

Ну это просто https://coollib.net/b/248007 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

5N62V пишет:

DIYMan пишет:

Короче - #define может как помочь, так и сделать великое, ужасное, чудовищное зло. Так же, как кухонный ножик - им можно резать салатик, а можно - соседа Васю за его пение невпопад, а в особенности за то, что эта сволочь сфальшивила, и вместо Си второй октавы спела Си-бемоль. 

Сосед Вася может быть импровизировал в стиле джаз, а Вы его ножичком..... 

Не я, соседка Васина. Я просто мимо проходил :)

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Иван_123 пишет:

А какие книги посоветуете для (далее следует очень нелюбимое форумчанами слово) новичка? 

DIYMan пишет:

трупа страуса и Майерса, Кента Бека ещё, про экстремальное программирование - зашла книжка, Герба Саттера, ну и, конечно, Герберта Шилдта. 

Иван_123
Offline
Зарегистрирован: 17.01.2018

Я просто не был уверен что это для начинающих

sadman41
Онлайн
Зарегистрирован: 19.10.2016

DIYMan пишет:

sadman41 пишет:

А если переменные инициализировать в каждом блоке - они не износятся раньше времени? А то я переживаю...

Истираются, но только с боков, и только - по нечётным дням недели. А в шаббат вообще - каждая третья не инициализируется.

Я так понимаю, что где-то далее пойдет речь про подоходный налог с операций присвоения, возврат НДС при операциях вычитания и, возможно, даже церковная десятина нарисуется...

Кстати, Винни забыл про заемный капитал, как основной движитель вперед. Полагаю, что где-то в районе setup() нужно эту операцию проводить и тогда прошивка стартанет гораздо быстрее.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

sadman41 пишет:

Я так понимаю, что где-то далее пойдет речь про подоходный налог с операций присвоения, возврат НДС при операциях вычитания и, возможно, даже церковная десятина нарисуется...

Щас винни прояснит, я в таких тонких материях не очень :)

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Иван_123 пишет:

Я просто не был уверен что это для начинающих

Не бойтесь - просто начните читать.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ну про вывод в офшоры я говорить не буду.  Конечно основную информацию можно хранить на сервере(мастере), но не жалуйтесь если вы окажетесь колонией(слейв), тогда основные капиталы оперативы будут потрачены на добычу и первичную переработку ресурсов и отправку их метрополии(серверу).

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Иван_123 пишет:

Я просто не был уверен что это для начинающих

Ну почему нормальное чтиво что дал DIYMan, но новичкам нужна еще говнотерапия. Потому что они они очень ленивые. Поэтому я и кинул свой источник. Может вы проведете эту терапию самостоятельно, не вынося этот процесс на форум.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:

Но компилятор действительно бормочет:

sketch_feb03a.ino:5:26: warning: comparison is always true 

Во-во. И цикл становится бесконечным. А в IDE по умолчанию предупреждения подавлены, чтобы не пугать лохов, так что это может стать серьёзной проблемой.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

5N62V пишет:

Вы имеете ввиду, что с точки зрения оптимизации и переносимости стоит писать

#define SIZE 10;


#if (SIZE<256)
       for( unsigned char i = 0; i<SIZE; i++) 
#elif  (SIZE>256 && SIZE< 65535)
       for( unsigned int i = 0; i<SIZE; i++)
#else
       for( unsigned long i = 0; i<SIZE; i++)
#endif
{.............}

Мне это кажется паранойей. Я ответил просто типа "забавный теоретический квирк", но не более того. на практике предпочитаю держать в уме какие у меня типы и думать, что пишу. Да и предупреждения компилятора не выключаю - они меня не пугают, а помогают, если где-то лопухнулся.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

DIYMan пишет:

Ну вы же понимаете, что дурак может и стеклянный хрен сломать, правда? 

Да, чего там стеклянный - и стальной не слабо!

DIYMan пишет:

по умолчанию в настройках IDE эти предупреждения "заботливо" отключены...

Во-во, для удобства новичков, что компилятор их своими глупостЯми не пужал :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:

А если переменные инициализировать в каждом блоке - они не износятся раньше времени? А то я переживаю...

Чтобы не было проблем, необходимо регулярно перечислять денюжку на аммортизацию. Могу счёт подсказать. Вам в вебманях или в пэйпале удобнее?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

qwone пишет:

 У больших компьютеров память для программ и память для переменных это одно большое ОЗУ. 

Ох не скажите! У самых больших там иногда такие затейливые архитектуры встречаются.