Оператор Switch: синтаксис с несколькими переменными
- Войдите на сайт для отправки комментариев
Ср, 11/11/2015 - 13:50
Подскажите пожалуйста, можно ли этим оператором проверять несколько переменных? Каков тогда будет синтаксис Switch и case?
нет, либо переменная, либо выражение
http://cppstudio.com/post/306/
А можно уточнить, что Вы понимаете под выражением "проверять несколько переменных"? Пример можно?
А можно уточнить, что Вы понимаете под выражением "проверять несколько переменных"? Пример можно?
Ну типа:
Switch (A, B, C...)
case (1, 5, 3...):
case (3, 2, 4...):
Но собственно я уже понял, что нельзя.
Почему сразу и нельзя? Огласите весь список! В смысле детальнее что хотелось-то .. что такое в вашем понимании 1,5,3 и особенно многоточие в данном синтаксисе? Значения переменной А или это тройки значений? А многоточие?
Господа хорошие, что ж вы паритесь-то ?
В описании явно написано, "оператор switch сравнивает значение переменной со значением, определенном в операторах case. Когда найден оператор case, значение которого равно значению переменной, выполняется программный код в этом операторе."
Ну всё же ясно и однозначно прописано, или как ?
В описании явно написано, "оператор switch сравнивает значение переменной со значением, определенном в операторах case. Когда найден оператор case, значение которого равно значению переменной, выполняется программный код в этом операторе."
Ну всё же ясно и однозначно прописано, или как ?
Конечно, "или как". Жизнь сложна. Ну, например, ситнтаксис, предложенный ТС (только без многоточий) вполне приемлем. Что будет при этом делаться - другой вопрос, но мы ведь и не понимаем чего он хочет, чтобы делалось! Потому и хочется понять, что именно нужно ТС. Беда только в том, что он, похоже, сам этого не понимает.
Ну, а даже если исходить из узкого понимания, что там могуть быть только переменные, кто сказал, что переменная обязана быть скалярной? Тоже есть варианты, только вот понять бы чего хочет ТС, но как я уже сказал, боюсь, что этого не понимает никто, включая и его самого.
bifurkas,
что значит "ну, типа". Может Вы объясните что Вы хотите сделать? Сравнить несколько чисел по-отдельности или там сравнить их среднее или сравнить их с датой Пасхи в 2345 году? Что Вам нужно-то?
А вообще, лучший способ что-то узнать - поэкспериментировать.
Вот, например, возьмите вот такой кусок кода
int a = 1, b = 2, c = 3; switch (a,b,c) { case 1 : Serial.println("Point #1"); break; case 2 : Serial.println("Point #2"); break; case 3 : Serial.println("Point #3"); break; default: Serial.println("Point #4"); break; }Запустите и посмотрите, что выдастся в Serial. Подумайте. Поменяйте код и проверьте адекватно ли он работает (и, стало быть, правильно ли Вы его понимаете). Если нет - подумайте ещё. Так Вы гораздо быстрее научитесь, чем задавая вопросы которые толком не можете сформулировать и ответы на которые (уверен) толком не можете понять.
В описании явно написано, "оператор switch сравнивает значение переменной со значением, определенном в операторах case. Когда найден оператор case, значение которого равно значению переменной, выполняется программный код в этом операторе."
Ну всё же ясно и однозначно прописано, или как ?
Конечно, "или как". Жизнь сложна. Ну, например, ситнтаксис, предложенный ТС (только без многоточий) вполне приемлем. Что будет при этом делаться - другой вопрос, но мы ведь и не понимаем чего он хочет, чтобы делалось! Потому и хочется понять, что именно нужно ТС. Беда только в том, что он, похоже, сам этого не понимает.
Ну, а даже если исходить из узкого понимания, что там могуть быть только переменные, кто сказал, что переменная обязана быть скалярной? Тоже есть варианты, только вот понять бы чего хочет ТС, но как я уже сказал, боюсь, что этого не понимает никто, включая и его самого.
Спасибо, что подробно растолковали мне, что я ничего не понимаю, но ответ я уже получил, можно не напрягаться.
Так Вы получили грубый ответ (без тонксотей). А если учесть тонкости, то (если я правильно понимаю, чего Вы хотите), всё "более чем возможно". Впрочем, я не навязываюсь. Вам жить.
А если учесть тонкости, то (если я правильно понимаю, чего Вы хотите), всё "более чем возможно
Это просто мои мысли вслух, а не замечания участникам дискуссии. На мой взгляд, рассматриваемый пример - типичный вариант "недокументированных возможностей", порожденных ошибками входного контроля компиллятора. В языке четко задана конструкция оператора. Программист нарушает синтаксис оператора, а компиллятор, вместо того, чтобы выявить недопустимую конструкцию, пропускает ее и КАК-ТО транслирует. МК это "как-то" отрабатывает. Пусть результат будет любопытен или даже приемлем, я категорически рекомендую избегать таких ситуаций, а сам факт пропуска компиллятором недопустимой конструкции заносить в "чек лист" для исправления в следующем релизе компиллятора. Нет никаких гарантий, что мы зарегистрировали весь объём результатов "недобросовестной компилляции", а не какую-то его часть. Плюс к этому, в следующем релизе компиллятора его реакция на тот же самый "кривой" исходный текст может быть совершенно другой.
switch(abc){ case a: switch(a){ case a1: // break; case a2: // break; case a3: // break; } break; case b: switch(b){ case b1: // break; case b2: // break; case b3: // break; } break; case c: switch(c){ case c1: // break; case c2: // break; case c3: // break; } break; }Сова, а как мы всё это в 32КБ флеша поместим?
А если учесть тонкости, то (если я правильно понимаю, чего Вы хотите), всё "более чем возможно
В switch допускается выражение и это документировано. Запись a,b,c является абсолютно нормальным выражением, использующим вполне себе докуметированную операцию "запятая". Результатом этого выражения будет результат последнего из разделённых запятыми подвыражений. Это абсолютно чётко документировано в языке. Точно также (и по тем же причинам) допустимо, например, switch (a, b+c). Выражение в скобках опять же использует операцию "запятая" и его результатом будет результат последнего, то бишь b+c.
Для чего такие конструкции нужны? Обычно для "побочных эффектов" вычисления первого выражения. Ну. вот, например, не лишённые какого-то смысла примеры:
switch (DebugPrint("Switch with: %d", a), a) { switch (++gCounter, Calculate()) { // глобальный gCounter увеличивается до вызова Calculate() switch (a = digitalRead(3), b = digitalRead(4), (a<<1) + b) {Если Вы о моих словах "возможны нюансы", так опять же никаких недокументированных фокусов. Например, если надо чтобы case сравнивал сразу три константы с тремя заданными в switch переменными, это легко делается путём введения векторного типа данных (абсолютно легальными и документированными средствами).
Вау, а тема-то не такая простая оказалась.. Спасибо, узнал новое.
да уж, ЕвгенийП оказался не простым кнопкодавом, его без страуструпа не возьмешь )
да уж, ЕвгенийП оказался не простым кнопкодавом, его без страуструпа не возьмешь )
ЕвгенийП в какой-то ветке писал, что он профессиональный програмист. Его точно не возьмёшь.
Чем проще код, тем меньше шансов допустить ошибку. switch(a,b,c) безусловно писать можно, только код это усложняет, а не упрощает. Читается код с запятыми сложнее, а значит и больше шансов допустить ошибку. Поскольку мы работаем группами, я бы за такой код своим сотрудникам кое что оторвал. Впрочем уговаривать не вижу смысла, каждый мочит как он хочет. Или лучше так: грабли у каждого свои! :)
ЕвгенийП в какой-то ветке писал, что он профессиональный програмист. Его точно не возьмёшь.
образование у него профильное, но если бы я был профессиональным программистом, то я бы здесь хернёй не страдал.
советовал он мне вписать в класс для кнопки частный случай - аргументировать причину непонятного не смог.
поэтому, гложут меня смутные сомнения по поводу профессионализьму.
Например, как Вам вот такой макрос с активным использованием запятой:
#ifdef DEBUG #define TRACED(v,MivV,MaxV) ((v < MivV || v > MaxV) ? Serial.print("*** v вылезло за границы:"),Serial.print(v):0), v #else #define TRACED(v, ...) v #endifТеперь, везде, где допустимо писать целочисленную переменную (в том числе и в switch), я могу заодно указывать её допустимые границы (т.е. вместо просто n писать TRACED(n, 10, 40), например. Если в моём коде DEBUG не определён, то это абсолютно всё равно, что писать просто n, а если я вставлю #define DEBUG, то породится код проверки переменной на допустимость границ и если она вылезла - пойдёт сообщение в Serial.
Не скажете же Вы, что это бесполезно или что это ухудшает читабельность кода? И полезно и не ухудшает ни читабельности, ни эффективности (если убрать "#define DEBUG", так как будто ничего и вовсе не было).
А вот написать такое без операции "запятая" было бы проблематично. По крайней мере, написать так, чтобы это можно было использовать везде, где допустима численная переменная.
Так что, весьма полезная конструкция, если пользовать с умом.
Если Вы о моём примере со switch(a,b,c), то Вы совершенно неправы. Там нет ничего недокументированного и нестандартного.
Это просто мои мысли вслух, а не замечания участникам дискуссии.
На правоту претендовать не берусь, поскольку не сишник ни разу. Мой пост не претензия, а ассоциация, навеянная опытом "прошлой жизни".
Чем проще код, тем меньше шансов допустить ошибку. switch(a,b,c) безусловно писать можно, только код это усложняет, а не упрощает.
100%
Поскольку мы работаем группами, я бы за такой код своим сотрудникам кое что оторвал.
200% :))
Опять же ассоцияция, теперь с уже более милым моему сердцу "железным" подтекстом. Схема, где на один единственный операционник навешаны: его собственная частотная коррекция, П-регулятор, И-регулятор, Д-регулятор, сумматор, коррекция нуля. Можно так? Да. Даже серийные изделия выпускались с таким решением. После наладки в цеховых условиях возникает однозначное желание "зачистить" автора.
Поддержу Евгения П. А ведь есть ещё "препроцессор", с помощью которого можно и ваще иной смысл этому синтаксису задать. В смысле switch с переменными через запятые .. ну вызовется требуемый макрос .. делов-то. Впрочем, один из вариантов его применения он тут уже описал. :)
Вот поэтому и спросил "чего хочет афтар" ..
советовал он мне вписать в класс для кнопки частный случай - аргументировать причину непонятного не смог.
По-поводу того случая, действительно я не смог объяснить (раз Вы не поняли, значит не смог). Но это не значит, что совет был плохим. Я Вам советовал вставить виртуальные функции для различных событий - это абсолютно стандартная схема для реализации любых классов с событиями. Я не знаю ни одной профессиональной системы, где этого бы не было.
Вот, например, посмотрите, например, как это реализовано в браузере. Любой элемент имеет кучу связанных событий (onclick - нажали, onmouseover - мышом наехали, onchange - изменили содержимое и т.д. их там десятки - вот здесь есть список http://www.irt.org/articles/js058/ ). Разбор событий производится всегда внутри класа, а когда программа класса посчитает, что событие произошло, она тупо вызывает соответсвующую виртуальную функцию. Внутри класса они (функции) все есть, но все пустые. Юзер может их определить, если они ему нужны, причём определить только те, которые ему нужны. Вот, допустим, нужно мне обрабатывать нажатие - я пишу свою функцию onclick и обрабатываю как мне нужно, и никакх других функций я не пишу. И разбор IF'ами было нажатие или нет - не моё дело - класс сам это разберёт и вызовет мой обработчик. Так делают все и всегда. Разбор событию юзеру не оставляют - это делает класс сам.
Ну, а по самой истории, Вы тогда просили меня написать Вам пример класса - я написал, Вы попросили написать ещё пару примеров, я опять же их Вам написал. А потом Вы, когда Вы сделали класс с помощью этих примеров, но не поняли моих объясниений про виртуальные функции, Вы обозвали меня сами помните как. Я прошу Вам изиниться и хочу нормализовать отношения.
Клапауций, вот знаете, тут многое было сказано, но я не хочу с Вами ссориться. а хочу восстановить нормальные отношения.
я с вами не ссорился - просто вы мне вынесли мосг странным.
по сути сабжа:
использовать класс первым предложил roman2712@ma #24
затем на бульдозере въехали вы, судя по вопросу, топик выше не читавший #31
затем, медленный вынос мосга - вам нравится эдкое в коде, но эдакое странно пока не знаешь нормального.
затем Tomasina дал ссылку на реальный пример #49
посидел я пытаясь понять, что не так в ваших примерах - плюнул и пошёл рыть интернет на тему.
*извиняться за что? я вас чем-то оскорбил? не наблюдаю - моя субъективная оценка, не более.
*извиняться за что? я вас чем-то оскорбил? не наблюдаю - моя субъективная оценка, не более.
upd. помню, что посылал Дохтора с его свитчами - вас по поводу класса не помню. последнее ваше собщение не свидетельствует об оскорблении #81
Например, как Вам вот такой макрос с активным использованием запятой:
#ifdef DEBUG #define TRACED(v,MivV,MaxV) ((v < MivV || v > MaxV) ? Serial.print("*** v вылезло за границы:"),Serial.print(v):0), v #else #define TRACED(v, ...) v #endifТеперь, везде, где допустимо писать целочисленную переменную (в том числе и в switch), я могу заодно указывать её допустимые границы (т.е. вместо просто n писать TRACED(n, 10, 40), например. Если в моём коде DEBUG не определён, то это абсолютно всё равно, что писать просто n, а если я вставлю #define DEBUG, то породится код проверки переменной на допустимость границ и если она вылезла - пойдёт сообщение в Serial.
Не вижу особых причин, почему бы отдельной строкой написать TRACED (разумеется исправив его) и только там, где нужно, а не в куче мест, а 'n' использовать как обычно, без ..эээ.. особенностей. Это будет более читабельно, для любого человека, который будет разбирать Ваш текст. Ответ "пишу для себя" не катит.
Теперь, цитирую: "везде, где допустимо писать целочисленную переменную". Ок. Для разминки такой текст, всё таки не везде:
void loop() { int n = 20; TRACED(n,10,40) = 50; int a = TRACED(n,10,40); Serial.println(a); }Это же подтвердил и MS VS 2010.
Разумеется это пример не самый лучший, бессмысленно ставить это с правой стороны, поскольку 'n' здесь не меняется, но прозвучало слово "везде". Я не критикую и не докапываюсь, просто некое предупреждение тому, кто захочет воспользоваться таким макросом. Самое плохое, что ошибка, выдаваемая компилятором далеко не способствует, чтобы понять, что в этом коде некорректно, думаю человек "с нуля" будет в шоке от такого сообщения.
В детстве я тоже любил навороченный код, вот только со временем стал писать даже простые операторы в фигурных скобках после if, for и т.п. В выражениях я теперь всегда пишу скобки, чтобы не парить мозг и коллег порядком вычисления. Конструкции типа switch(a++) тоже не пишу. Да и достаточно примеров, и так уже нанудил много.
Хоть я, наверное, повторюсь, но в МК #define может быть и нормально, на больших компах в C++ он не рекомендуется, хотя это совсем другая история и не для этого форума.
Вооббще-то, я писал лишь о полезности запятой и вовсе не писал, что использовать такую запись нужно везде. Разумеется, только там где действительно надо контролировать значение n. Ну, а про использование слева - молодец, что заметил :)))
Привычка. Доверяй, но и сам не плошай :)
Пусть я буду нудным, но слово 'везде' я цитировал, я его не придумал и не вырвал из контекста.
Трюки в программировании хороши, пока проект выполняется в моно режиме, я сам так много работал и делал 'перлы', а потом понял, что это хорошо только для себя, типа я такой крутой. Почитал, пописал, повзрослел и понял Истину :)