Вопрос на логику (Функции и циклы)
- Войдите на сайт для отправки комментариев
Втр, 16/08/2016 - 09:23
Всем привет! Не могу ответить на свой вопрос сам, решил спросить вас))
Есть функция, в которой вложен бесконечный цикл.
bool read(char *buffer, int count, unsigned int timeout= DEFAULT_TIMEOUT, unsigned int chartimeout= DEFAULT_INTERCHAR_TIMEOUT) { int i = 0; unsigned long timerStart, prevChar; timerStart = millis(); prevChar = 0; while(1) { while (sim_check_readable()) { char c = Serial1.read(); prevChar = millis(); buffer[i++] = c; if (i >= count) { //break; return true; } } if (i >= count) break; if ((unsigned long) (millis() - timerStart) > timeout * 1000UL) { //break; return false; } //If interchar Timeout => return FALSE. So we can return sooner from this function. Not DO it if we dont recieve at least one char (prevChar <> 0) if (((unsigned long) (millis() - prevChar) > chartimeout) && (prevChar != 0)) { // break; return false; } } }
Вопрос - как правильно разрывать бесконечный цикл? Break - прервывает цикл, Return должна возвратить значение Ture или False в зависимости от выполнения фукнции. Дак вот правильно ли я делаю в этом коде выходя из цикла командой Return? или надо сначала break а потом Return?
как написано - правильно.
что вернёт функция в этом случае?
А что именно Вас смущает? Тогда и ответить можно.
Просто "правильно" понятие широкое. Например, если Вы спрсоите фаната "структурного программирования" (есть такая секта), то он Вам скажет, что функция (как и цикл) должна иметь только один вход и один выход, а у Вас они имеют по три. Если же Вы спросите человека? привыкшего к низкоуровневым делам, он скажет. что всё у Вас нормально. А если Вы спросите зануду - педанта эффективности, он скажет, что необходимо поменять местами условия в строке 25, т.к. второе явно быстрее первого :)
т.е 25 строка теперь выглядеть так должна if ((prevChar != 0) && ((unsigned long) (millis() - prevChar) > chartimeout)) ?
Дак все таки, return прервет цикл с возвратом результата? или нужно остановить цикл, а потом снова проверив условия вернуть результат? ))
Да, нормально он его прервёт, не парьтесь.
А про ту строку, видите, если компилятор генерирует т.н. "ленивую логику", то когда условия соединены по И, он генерирует проверку первого и, если оно false, то второе не проверяется вовсе. Поэтому первым обычно ставят то, кторое чаще бывает false или более дешёвое по проверке (чтобы дорогое хоть иногда не проверять). А если поставить наоборот, то дорогое будет проверяться всегда.
Спасибо большое! ))
как написано - правильно.
что вернёт функция в этом случае?
Ууупс )) пропустил эту поправку))
Ууупс )) пропустил эту поправку))
Странно, что Вы её пропустили. Компилятор Вам про это говорил. Если у Вас выключены предупреждения (они выключены по умолчанию в IDE) - включите. Сэкономит кучу времени и нервов.
Не правильно вы сказали про фанатов "структурного программирования". Фанаты "структурного программирования" воевали с GO ТО. И похоже победили. Сейчас GO ТО нигде не найдешь.
break
-это завоевание фанатов "структурного программирования" А вот "фанаты модульного проектирования" скорее проиграли. У них размер модуля должен быть с размером в экран. И несколько операторов в строке это их стиль.Не правильно вы сказали про фанатов "структурного программирования". Фанаты "структурного программирования" воевали с GO ТО.
Да, нет, "один вход и один выход" - это один из важнейших постулатов их символа веры, узко Вы их понимаете.
Сейчас GO ТО нигде не найдешь.
А искали?
http://arduino.ru/forum/programmirovanie/ostanovka-progi-halt-destroy-free
http://arduino.ru/forum/programmirovanie/chto-ne-tak-s-kodom-knopok
http://arduino.ru/forum/programmirovanie/vykhod-iz-preryvaniya-v-zadanoe...
http://arduino.ru/forum/programmirovanie/operator-goto-i-tsikl-while
http://arduino.ru/forum/programmirovanie/problema-s-operatorom-goto
И вообще, наберите goto в строке поиска в правом верхнем углу - под 200 результатов.
А в новейших стандартах языков программирования появляются такие варианты goto, что "мама не горюй". Как Вам goto с адресом перехода, хранящимся в переменной? Можете запустить на Ардуинке - без проблем работает.
Вот опять же . Или вы не знаете истоков, или специально дезинформируете.
Цитирую :Структу́рное программи́рование — методология разработки программного обеспечения, в основе которой лежит представление программы в виде иерархической структуры блоков. Предложена в 1970-х годах Э. Дейкстрой и др.
В соответствии с данной методологией любая программа строится без использования оператора goto из трёх базовых управляющих структур: последовательность, ветвление, цикл; кроме того, используются подпрограммы. При этом разработка программы ведётся пошагово, методом «сверху вниз».
https://goo.gl/L2yLMb
Я бы промолчал бы . Если бы сначала был в лагере тех, кто без GO ТО не мог программировать. А потом переучивался по Дейкстре. читал ее в переводе. И да блок-схемы расчитаны под GO TO программирование.
О, да Вы, Википедик! Правда, в той статье в Википедии было слишком много букв и Вы её до конца не осилили.
Откройте ту самую статью, которую Вы цитировали. Найдите там раздел "Принципы структурного программирования" и прочитайте принцип №6: "Все перечисленные конструкции должны иметь один вход и один выход".
Вам показать этот же "постулат веры" в первоисточнике? Или Вы уже поверили, что я знаю, о чём говорю?
P.S.
Кстати, существовали гнусные еретики, которые даже считали, что структурное программирование и использование goto не противоречит друг другу. Разумееется, это ересь, но надеюсь, что авторитет автора вот этой статьи и его право иметь и высказывать своё, уважаемое всеми программистами, мнение не вызывает сомнений?
Ууупс )) пропустил эту поправку))
Странно, что Вы её пропустили. Компилятор Вам про это говорил. Если у Вас выключены предупреждения (они выключены по умолчанию в IDE) - включите. Сэкономит кучу времени и нервов.
Абалдеть ))) включил эти галочки и теперь вижу еще мелкие косячки компиляции))) например
for(int i=0; i<strlen(cmd); i++) - ругается что сравниваются переменные не одинакового типа, signed и unsigned ))) созадал переменную int и в нее запихнул значение strlen, теперь не ругается))) хотя в целом то код работает, на что это могло повлиять не знаю... просто "правило хорошего тона"?
for(int i=0; i<strlen(cmd); i++) - ругается что сравниваются переменные не одинакового типа, signed и unsigned ))) созадал переменную int и в нее запихнул значение strlen, теперь не ругается))) хотя в целом то код работает, на что это могло повлиять не знаю... просто "правило хорошего тона"?
В некоторых случаях может повлиять, хотя часто не влияет. Лучше иметь привычку так не делать.