Оператор Switch или IF
- Войдите на сайт для отправки комментариев
Пнд, 17/10/2016 - 12:11
Добрый день! Можно ли для оператора Switch использовать диапазан значений? То есть вместо
witch (var) { case 1: .... break; case 2: .... break; .... .... }
Написать:
witch (var) { case 1 - 2: .... break; .... .... }
А то не сильно хочется писать так:
if (i > 40) {...; } if (i <= 40 && i > 30){...; } if (i <= 30 && i > 20) {...; } if (i <= 20 && i > 10) {...; } if (i <= 10) {...; }
http://stackoverflow.com/questions/12911691/switch-multiple-values-in-one-case
Печалька :(
У меня диапазан значений примерно 150. Похоже case здесь не поможет. Буду использовать If.
Можно еще, например, сделать константный массив граничных значений (часто достаточно хранить одну границу) и отдельную функцию, которая в цикле пробежится по массиву граничных значений и найдет нужный период. Впрочем можно пойти дальше, сделать структуру в которой одна из границ (какая - зависит от задачи) и ссылка на функцию-обрботчик. Дальше массив структур и тоже самое, отдельная функция, которая пробежится по массиву структур и вызовет соответствующий функцию обработчик. Короче, зависит от задачи, как обычно. Для одних задач мои варианты - как из пушки по воробьям, для других - простой способ сделать расширяемые/изменяемые диапазоны срабатывания.
Еще, нет особого смысла сравнивать обе границы, часто достаточно проверять одну границу и пользоваться конструкцией:
if(...) {} else if(...) {} else if(...) {} else {};
Здесь главное понять в каком направлении двигаться при сравнении, потому что здесь уже порядок сравнения важен.
К примеру, возять твой вариант:
И переписать его в такой:
Проще, может быть чуть-чуть сложнее для понимания, но если понятен смысл, то даже проще читаемый код.
Попробуйте так:
Спасибо, использовал If...elseIf . Для case слишком много значений пролисывать надо.
Т.е. как?
или
Спасибо, использовал If...elseIf . Для case слишком много значений пролисывать надо.
А чем Вам не понравился вариант, предложенный Uni? Мне казалось, что это как раз то, о чём Вы просили.
На самом деле такое использование называется gnu extension, т.е. это расширение c++, используемое в avr-g++ компиляторе. Программа будет не переносимой, если пользоваться такими расширениями. Их можно использовать, только нужно знать какие ограничения от этого могут быть.
Есть ряд таких расширений, кторые с одной стороны удобны, но с другой, к удобству быстро привыкаешь, что не всегда хорошо.
Вот, например:
В других компиляторах такое присвоение сделать нельзя, только при инициализации.
П.С. Да, кстати, эти расширения зависят от версии компилятора и, возможно, от выбранного стандарта языка (точно не помню).
Столько тонкостей я еще не знаю! uni, ЕвгенийП я наверное неправильно понял пример. Я подумал что вместо:
case
0 ... 10: {
break
; }
нужно писать:
case
0 1 2 3 4 5 6 7 8 9 10: {
break
; }
Тогда уж точно легче:
case
0 ... 10: {
break
; }
то это сделает код проще и читабельней (как на мой взгляд).Так, можно же. Другое дело, что, как Вам правильно коллега сказал, это расширение языка и в стандарте такого нет. Т.е. далеко не все компиляторы это поддерживают. Но, до тех пор, пока Вы живёте на gc/gcc - нет проблем. Т.е. проблем нет ни с Arduino-IDE, ни c AVR-студией.
Вот Вам готовый к запуску пример. Запустите, посмотрите. Вы вводите число, а он говорит в каокй диапазон оно попало.
Здорово!
Привык в Паскале к таким конструкциям, и здесь без них тяжело. Но, оказывается, они тоже есть, правда, набивать на целую точку больше.
Кстати, сразу вопрос: в других операторах, например, в if пользоваться диапазоном можно? Ну, например, есть ли аналог паскалевского?
if a in [1,3..7,10,12] then
Ну, блин, Вы уж хотите тип "множество" сюда засунуть :) Так напишите класс ручками.
А вообще, если интересуют расширения языка в GNU'сных компиляторах, то имеются полные списки для С и для С++ надо? Могу поискать.
Да мне бы пока с классическими С/С++ разобраться, а то пишу на некотором подмножестве конструкций, которые есть практически во всех языках.
Ну ладно, со множеством я, конечно, погорячился, а диапазон где-нибудь кроме case используется?
Вроде, нет. https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html#Case-Ranges
Похоже, что не только avr-gcc. GCC-ARM такое расширение принимает так же без вопросов.
Не все xxx-gcc компиляторы понимают расширения. Зависит от конкретной версии, т.е. когда вводилась поддержка того или иного расширения. Я, к примеру, пользуюсь 4.2.1 (специальный компилятор для работы с платой под uClinux), где не могу использовать присвоение структуре, как показывал выше. Потому что сборка устаревшая, а новой не собрано.
А вообще, если интересуют расширения языка в GNU'сных компиляторах, то имеются полные списки для С и для С++ надо? Могу поискать.
Было бы интересно на расширения Си посмотреть.
А то скучно: ЕвгенийП давно обещанный 3-й этюд про память не публикует :)
Было бы интересно на расширения Си посмотреть.
https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html#C-Extensions
Нафиг нужны эти расширения. Конечно, если сидишь в своём склепе и никуда не выходишь, может и нормально, но, не дай Бог, если придется переносить.. Уж не на столько они хороши, что бы на них западать. Разумеется, ИМХО, кому надо, тот юзает, не отговариваю.
Ага, некоторыми вы пользуетесь и даже не замечаете этого, как например объявление массива с изменяемым размером (variable length arrray). Недавно здесь товарищ просил помощи в работе с json и он там объявил буфер именно используя это gcc extension и кроме меня этого никто не заметил:
char
buf [JsonString.length()];
некоторыми вы пользуетесь и даже не замечаете этого
kisoft пользуется таким объявлением массивов? Боюсь, Вы его с кем-то путаете :)
кроме меня этого никто не заметил:
Да, ладно Вам, такие вещи невозможно не заметить - они глаз режут любому старому С'онисту.
kisoft мог бы заметить в той теме, что выделять память таким способом не хорошо и почему так, чего он не сделал. Обычно память динамически выделяется другим способом.
Уверяю Вас, он заметил.
Ну хорошо, если так. Дополнительная ссылка: Extensions to the C++ Language
ЕвгенийП, спасибо, всё в точку. :) Я слишком стар, чтобы не замечать новомодных фишек :) Как можно не заметить на улице зеленого жирафа в шлеме? ;)
uni, если я буду постоянно нудить, что так неправильно (впрочем, ничего особенного в таком массиве нет), то у меня не хватит времени на удовольствия и меня закидают гнилыми помидорами любители гоп-стопа, а их стало очень немало, а смысл с ними спорить? Я не вижу. Да тут и без меня хватает кому заметить ;) Зачем людям портить кайф? :)
Массив с динамической длиной уже всплывал ранее в форуме. Кстати, тогда я о нем и узнал (о таком расширении), но пользоваться - упаси Бог, не было нужды. К тому же я слишком консервативен в привычках, хотя новое я тоже иногда приветствую.
А самое главное, что я до сих пор прусь от программирования, потому оно для меня не только работа, но и хобби тоже :)
Прочитал на сайте ардуина.ру/программирование про оператор Switch. Там написаны такие слова:
"Ключевое слово break является командой выхода из оператора case и обычно используется в конце каждого case. Без оператора break оператор switch будет продолжать вычислять следующие выражения, пока не достигнет break или конец оператора switch. "
Вроде бы и с break и без него должно нормально работать. Попробовал
Все нормально работает.
Закомментировал все break , т.е убрал из скетча. Вроде бы судя по описанию должно нормально работать
но работает неправильно! Или я что-то не так понял?
но работает неправильно! Или я что-то не так понял?
Надо внутри case фигурные скобки поставить.
но работает неправильно! Или я что-то не так понял?
Надо внутри case фигурные скобки поставить.
А неправильно - это как?
Если совпало с первым, так все "совпалы" печатаются? Так оно так и должно работать. перечитайте описание. Или как-то по-другому?
А неправильно - это как?
Если совпало с первым, так все "совпалы" печатаются? Так оно так и должно работать. перечитайте описание. Или как-то по-другому?
Он будет продолжать вычисления, но не проверки. Если сказать проще, то он выполняет проверки до первого true, а с этого места начинает выполнять все подряд операции без проверок либо до конца switch, либ до первого break, что вперёд случится.
Он будет продолжать вычисления, но не проверки. Если сказать проще, то он выполняет проверки до первого true, а с этого места начинает выполнять все подряд операции без проверок либо до конца switch, либ до первого break, что вперёд случится.
Спасибо. Понял что без break конструкция просто бессмысленная.
без break конструкция просто бессмысленная.
Ну, я бы не стал так категорично. Всякие ситуации бывают. Например, в случае 1 что-то сделать, а в случае 2 сделать тоже самое, но предварительно подготовиться. Вот и ставишь case 2 выше, в ней размещаешь подготовку без break, а после неё ставишь case 1. Просто специфику работы надо знать и пользоваться.
Ну да...надо просто знать как работает, и использовать это в своих целях :)
Теперь буду знать.
У нас бывает достаточно часто такая конструкция (на больших компах), когда break специально убирается, чтобы упростить код. В таких случаях я не удаляю break, а комментарю строку и пишу, что break не нужен, чтобы потом не удивляться отсутствию break, поскольку отсутствие его воспринимается визуально как ошибка.
Понятно....А я думал что "switch будет вычислять" означает что будет проверяться условие, а оказывается это означает, что дальше он будет выполнять все что дальше написано.
Не нужно путать, кто что вычисляет.
Представьте, у нас есть N веток, а нам нужно выполнить единственную K-ю, причем K > 1 и K < N.
Оператор switch вычисляет адрес, на который нам нужно перейти и передает управление на начало K-го блока. Собственно, на этом его функции заканчиваются - дальше идет обычный последовательный код, и если мы хотим, чтобы ветки с K+1 до N были пропущены, мы должны явно это указать. Собственно break как раз и осуществляет переход с той строки, на которой он находится, на строку следующую за концом оператора switch (т.е. за закрывающей скобкой).
Т.е. нам нужно пропустить два фрагмента кода: первый с 1-го по К-й, а второй с К+1-го по N-й. Первый фрагмент пропускается благодаря оператору switch, а второй - break.
Всех приветствую. Столкнулся с проблемой в операторе switch. выбор происходит, но не могу найти решение, чтоб выбранный case работал бесконечно долго до момента поступления другого значения case.
Задача: - бесконечно долгая работа case 1, до выбора другого case 2, но в тоже время остальному коду не мешал работать.
- в case будет задержка реле 2 мин вкл, 5 выкл (бесконечный цикл), а в другом case другие временные интервалы. так же не знаю на чем реализовать.
Управление циркуляционным насосом делаю с разными периодами работы.
Спасибо.
Бесконечно крутится только loop()
Ну так зачем вы свой switch запихнули внутрь процедуры блинк?
Заведите переменную номер режима для кейса и внутри блинк делайте только установку этой переменной, а весь код вынесите в основную программу
Отличная идея. В программировании не селен, но сейчас испытаем. Спасибо!
Всех приветствую. Столкнулся с проблемой в операторе switch. выбор происходит, но не могу найти решение, чтоб выбранный case работал бесконечно долго до момента поступления другого значения case.
В программировании не селен ...
И даже не мышьяк.
Ну где-то так.
Пух, ну хватит людей пугать, он Blink от Blynk пока не отличает, а ты его автоматами грузишь.
Пух, ну хватит людей пугать, он Blink от Blynk пока не отличает, а ты его автоматами грузишь.
вот, вот, тут уже пару лет на форуме, а до автоматов ПУХа еще не добрался )))
Пух, ну хватит людей пугать, он Blink от Blynk пока не отличает, а ты его автоматами грузишь.
вот, вот, тут уже пару лет на форуме, а до автоматов ПУХа еще не добрался )))
занимайся лучше катушкой :)))
Пух, ну хватит людей пугать, он Blink от Blynk пока не отличает, а ты его автоматами грузишь.
Пух, ну хватит людей пугать, он Blink от Blynk пока не отличает, а ты его автоматами грузишь.
вот это поворот !
я надеюсь это будет мега-графический-класс-на автоматах?
Пух, ну хватит людей пугать, он Blink от Blynk пока не отличает, а ты его автоматами грузишь.
вот, вот, тут уже пару лет на форуме, а до автоматов ПУХа еще не добрался )))
занимайся лучше катушкой :)))
нечем, программа давно написана, работает как швейцарские часы, ни одного зависания нет, а код ПУХа всё же удалось посмотреть, остались вопросы, насколько код блокирующий? (время опроса кнопок) )))
Еще раз внимательно посмотрел, а ведь красиво написано и, чего его вы тут гнобили, зависть? )))