|
Название: Урок 15. Оператор switch. Отправлено: Hummer от Октябрь 16, 2011, 08:42:44 Многие операторы являются практическими решениями проблем, связанных с операторами низкого класса.
Допустим в игре рано или поздно наступает ситуация, когда нужно выбрать одно из n (к примеру 7) развитий действия. Например однажды (не будем учитывать когда) нужно либо прибавить 1, либо отнять 4, либо умножить на 1.5, либо поделить на 5. Всего: 4 действия. Случайность достигается функцией random(4). b=get_string('Введите число', 0) a=irandom(3) // объясним в конце урока if(a==0)//да, логичнее написать if !a, но этот способ нагляднее. По крайней мере оба метода разрешены { a+=1 } else if(a==1)//аналогично if a { b-=4 } else if(a==2) { b*=1.5 } else if(a==3) { b/=5 } show_message(string(b)) Много монотонных проверок могут замедлить выполнение программы, а также можно запутаться со скобками круглыми и фигурными. Модифицированным оператором if-else является оператор switch Код: switch(<выражение>) Выражение на множественную проверку стоит в скобках, рядом с ключевым словом switch. Как и у if выражение можно писать без скобок. Далее идёт "тело" оператора (ВНИМАНИЕ! фигурные скобки обязательны). Описание нового случая обозначается словом case. После идёт значение и обязательно двоеточие. Например { case <случай1>: <операторы1> break; case <случай2>: <операторы2> break; default: <операторы3> break; } Код: // Итак, заготовка решения нашей проблемы уже естьcase 1: //get_value() - скрипт case get_value(): // a=7 case a: // case 'QWERTY': // case object0: // и т д Код: a=irandom(3) Сначала, получим случайное число, затем при исполнении программа будет поочерёдно сравнивать a со всеми значениями, которые мы передали при помощи case. Как только нашлось совпадение, программа начинает выполняться от токи совпадения и вплоть до встречи слов break, continue или exit. По традиции (да и по здравому смыслу) используют break, потому что continue предназначено для другого (хотя и работает), а exit полностью выходит из кода. Для пущей уверенности код между break и case можно ограничить фигурными скобкамиswitch(a) { case 0: case 1: case 2: case 3: } Вот наш итоговый вариант Код: switch(a) Прежде чем перейти к новой метке (метка - слово, выделяемое двоеточием, например case), я, пользуясь случаем, напомню о ещё одних операторах. Действие с присваиванием. { case 0: a+=1 break; case 1: a-=4 break; case 2: {a*=1.5} break; case 3: {a/=5} break; } Допустим a=7, а b=1. После действия b=a+1 переменная а останется с тем же значением, но запись a+=1 её изменит на 1. Попроще это будет так: a+=1 эквивалентно a=a+1 a-=1 экв. a=a-1 a*=1 экв. a=a*1 и т д, НО! a-=1 неэкв. a=-1. Также хочу обратить ваше внимание на то, что если вы используете изменение с присваиванием, то переменная, которую вы изменяете уже должны быть объявлена. g/=2 // ошибка: эвк. g=g/2, но g ещё не объявлена. Кроме case, switch принадлежит метка default. Она применяется только тогда, когда ни одного совпадения из case'ов не произошло. К примеру Код: a=irandom(100) В принципе после последней метки break можно не указывать, так как там естественный выход из оператора. switch(a) { case 0: show_message('Ноль') break; case 1: show_message('Один') break; default: show_message('Очень много') break; } Покажу преимущества оператора switch и этих нудных меток, а также почему важно ставить break. Дело в том, что break в switch не является требованием языка. Он может и отсутствовать. Тогда всё равно смысл выполнения сохранится Цитата: Чуть выше программа будет поочерёдно сравнивать a со всеми значениями, которые мы передали при помощи case. Как только нашлось совпадение, программа начинает выполняться от токи совпадения и вплоть до встречи слов break Приведу пример. Заранее скажу, что не стоит искать в нём глубокого смысла. Он приведён только для демонстрации синтаксиса.Код: a=irandom(9) Как только найдёно совпадение, программа напролом будет выполнять все действия до break, независимо: есть совпадение дальше или нет.switch(a) { case 1: case 3: case 5: case 7: case 9: show_message('Нечётное число '+string(a)); break; case 0: case 2: case 4: case 6: case 8: show_message('Чётное число '+string(a)) break; default: show_message('Ошибка'); } Но несмотря на всё это, у if-else есть пара преимуществ. Например в булевой логике. Вот две равносильные записи Код: if(a<b)//предполагается, что а и b уже объявлены и { // } else { // } Код: switch(a<b) Производительнее и понятнее будет первая запись. Отсюда следует, что если выражение на множественную проверку может принимать только ture и false значения, то лучше (предпочтительнее) воспользоваться if-else.{ case true: // break; case false: // break; } Все операторы, имеющие тела (if, if-else, switch, while, for и т д) можно "вкладывать" друг в друга. Код: switch(a) { case 0: // break; case 7: // break; case 45: switch(b) { case 2: // break;//прерывает только внутренний оператор case 8: // break; default: // } break;//прерывает уже внешний default: // } Примеры глупого использования switch Код: switch(константа)//всегда одно значение switch(a) { case 5: //лучше воспользоваться if } switch(b)//всегда выполнится { default: } switch(a==b)//обговорено выше { case true: break; case false: break; default://вообще лишнее. никогда не выполнится } Также switch можно использовать в скриптах. Тогда return тоже будет выступать в качестве прерывания switch, но одновременно будет выходить из скрипта. Чуть не забыл об одном важном преимуществе switch. Дело в том, что вычисление значения выражения будет происходить единожды, в отличии от множественного if. Особенно это важно в случайных числах. Код: a=irandom(4) switch(a) { } //равносильно switch(irandom(4)) А если вы делаете множественную проверку случайного числа при помощи if-else, то сначала это число стоит занести в переменную. Удачи! Название: Re: Урок 15. Оператор switch. Отправлено: Nick от Октябрь 16, 2011, 19:02:16 Отлично, спасибо. +1 sm_respekt
Всегда путался в switch'ах, а щас вроде разобрался. Название: Re: Урок 15. Оператор switch. Отправлено: DarkWing [GB] от Октябрь 26, 2011, 23:29:54 Мне нужно что-бы по двум разных значениям выполнялся один и тот-же кусок кода.
Т.е.: Код: switch(a) { case 0: (код 0); break case 1: (код 1); break case 2: (код 2); break case 3: (тоже код 2); break } Понятно, что можно это решить простым копированием "кода 2" в case 3, но этот фрагмент кода очень большой, и постоянно редактируется-исправляется. Как это можно оптимизировать? Хотелось-бы что-то вроде конструкции: Код: case 2,3: (код 2); break Название: Re: Урок 15. Оператор switch. Отправлено: YellowAfterlife от Октябрь 26, 2011, 23:35:06 Мне нужно что-бы по двум разных значениям выполнялся один и тот-же кусок кода. Т.е.: Код: switch(a) { case 0: (код 0); break case 1: (код 1); break case 2: (код 2); break case 3: (тоже код 2); break } Понятно, что можно это решить простым копированием "кода 2" в case 3, но этот фрагмент кода очень большой, и постоянно редактируется-исправляется. Как это можно оптимизировать? Хотелось-бы что-то вроде конструкции: Код: case 2,3: (код 2); break Код: switch(a) { // ... case 2: case 3: // code 2, 3 break; } Название: Re: Урок 15. Оператор switch. Отправлено: Dmi7ry от Октябрь 26, 2011, 23:59:17 Угу, прям в справке такой пример есть:
Код: switch (keyboard_key) { case vk_left: case vk_numpad4: x -= 4; break; case vk_right: case vk_numpad6: x += 4; break; } Название: Re: Урок 15. Оператор switch. Отправлено: DarkWing [GB] от Октябрь 27, 2011, 00:34:27 Ага, спасибо! Работает.
Название: Re: Урок 15. Оператор switch. Отправлено: Hummer от Октябрь 27, 2011, 05:05:53 Покажу преимущества оператора switch и этих нудных меток, а также почему важно ставить break. Обидно. Такое ощущение, что совсем не читал. :getlost:Дело в том, что break в switch не является требованием языка. Он может и отсутствовать. Тогда всё равно смысл выполнения сохранится Цитата: Чуть выше программа будет поочерёдно сравнивать a со всеми значениями, которые мы передали при помощи case. Как только нашлось совпадение, программа начинает выполняться от токи совпадения и вплоть до встречи слов break Приведу пример. Заранее скажу, что не стоит искать в нём глубокого смысла. Он приведён только для демонстрации синтаксиса.Код: a=irandom(9) Как только найдёно совпадение, программа напролом будет выполнять все действия до break, независимо: есть совпадение дальше или нет.switch(a) { case 1: case 3: case 5: case 7: case 9: show_message('Нечётное число '+string(a)); break; case 0: case 2: case 4: case 6: case 8: show_message('Чётное число '+string(a)) break; default: show_message('Ошибка'); } Название: Re: Урок 15. Оператор switch. Отправлено: Dmi7ry от Октябрь 27, 2011, 08:08:34 Код: case 8: show_message('Чётное число '+string(a)) break; default: show_message('Ошибка'); Название: Re: Урок 15. Оператор switch. Отправлено: Hummer от Октябрь 27, 2011, 12:01:14 :facepalm:
давно пора выучить, что ; в ГМ практически не играет никакой роли (только в операторе for, но об этом на следующем уроке) Название: Re: Урок 15. Оператор switch. Отправлено: Dmi7ry от Октябрь 27, 2011, 12:14:22 М... Я был уверен, что несколько операндов в одной строке не разделённые ; вызовут ошибку. Буду знать, что нет.
Но лучше всё же использовать - как минимум, это вырабатывает хороший стиль программирования и будет гораздо меньше проблем при переходе на тот же Си... Название: Re: Урок 15. Оператор switch. Отправлено: DarkWing [GB] от Октябрь 27, 2011, 14:18:14 Просто логику не уловил сходу...
Думал, что раз встретился один "Case", который не подходит, то дальше ГМ пропускает весь код относящийся к этому Case, и ищет следующий Case, который подойдет. И из приведенного примера я был уверен до сего момента, что программа даст сообщения ТОЛЬКО на значениях 9 и 8 !!! Неплохо-бы пояснять, что именно должен выдавать приведенный пример... Название: Re: Урок 15. Оператор switch. Отправлено: Hummer от Октябрь 27, 2011, 18:06:15 Я попозже приведу фотографии с пояснением. Ждите.
Название: Re: Урок 15. Оператор switch. Отправлено: Peexal Studio от Июль 17, 2017, 12:36:46 Можно ли применить этот самый свич для кода instance_create, чтобы расставить объекты по необходимым координатам в комнате?
Название: Re: Урок 15. Оператор switch. Отправлено: Solar Off Roader от Ноябрь 30, 2023, 10:42:13 Добрый день! sm_hi3 Подскажите пожалуйста, как такую логику завернуть в switch & case, это можно сделать?
Код: if (level[i][k][0] = 100 and level[i][k][1] = 1) { instance_create_layer(xx, yy, "Instances", Obj_construction_left); } if (level[i][k][0] = 100 and level[i][k][1] = 2) { instance_create_layer(xx, yy, "Instances", Obj_construction_right); } if (level[i][k][0] = 100 and level[i][k][1] = 3) { instance_create_layer(xx, yy, "Instances", Obj_construction_center); } Название: Re: Урок 15. Оператор switch. Отправлено: Xageu от Ноябрь 30, 2023, 15:26:40 Добрый день! sm_hi3 Подскажите пожалуйста, как такую логику завернуть в switch & case, это можно сделать? Код: if (level[i][k][0] = 100 and level[i][k][1] = 1) { instance_create_layer(xx, yy, "Instances", Obj_construction_left); } if (level[i][k][0] = 100 and level[i][k][1] = 2) { instance_create_layer(xx, yy, "Instances", Obj_construction_right); } if (level[i][k][0] = 100 and level[i][k][1] = 3) { instance_create_layer(xx, yy, "Instances", Obj_construction_center); } Код: if level[i][k][0] == 100 { switch level[i][k][1] { case 1: //code break case 2: //code break case 3: //code break } } |