Многие операторы являются практическими решениями проблем, связанных с операторами низкого класса.
Допустим в игре рано или поздно наступает ситуация, когда нужно выбрать одно из 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(<выражение>)
{
case <случай1>: <операторы1> break;
case <случай2>: <операторы2> break;
default: <операторы3> break;
}
Выражение на множественную проверку стоит в скобках, рядом с ключевым словом switch. Как и у if выражение можно писать без скобок. Далее идёт "тело" оператора (ВНИМАНИЕ! фигурные скобки обязательны). Описание нового случая обозначается словом case. После идёт значение и обязательно двоеточие. Например
//
case 1:
//get_value() - скрипт
case get_value():
//
a=7
case a:
//
case 'QWERTY':
//
case object0:
// и т д
Итак, заготовка решения нашей проблемы уже есть
a=irandom(3)
switch(a)
{
case 0:
case 1:
case 2:
case 3:
}
Сначала, получим случайное число, затем при исполнении программа будет поочерёдно сравнивать a со всеми значениями, которые мы передали при помощи case. Как только нашлось совпадение, программа начинает выполняться от токи совпадения и
вплоть до встречи слов break, continue или exit. По традиции (да и по здравому смыслу) используют break, потому что continue предназначено для другого (хотя и работает), а exit полностью выходит из кода. Для пущей уверенности код между break и case можно ограничить фигурными скобками
Вот наш итоговый вариант
switch(a)
{
case 0: a+=1 break;
case 1: a-=4
break;
case 2: {a*=1.5}
break;
case 3:
{a/=5}
break;
}
Прежде чем перейти к новой метке (метка - слово, выделяемое двоеточием, например case), я, пользуясь случаем, напомню о ещё одних операторах. Действие с присваиванием.
Допустим 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)
switch(a)
{
case 0: show_message('Ноль') break;
case 1: show_message('Один') break;
default: show_message('Очень много') break;
}
В принципе после
последней метки break можно не указывать, так как там естественный выход из оператора.
Покажу преимущества оператора switch и этих нудных меток, а также почему важно ставить break.
Дело в том, что break в switch не является требованием языка. Он может и отсутствовать. Тогда всё равно смысл выполнения сохранится
программа будет поочерёдно сравнивать a со всеми значениями, которые мы передали при помощи case. Как только нашлось совпадение, программа начинает выполняться от токи совпадения и вплоть до встречи слов break
Приведу пример. Заранее скажу, что не стоит искать в нём глубокого смысла. Он приведён только для демонстрации синтаксиса.
a=irandom(9)
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('Ошибка');
}
Как только найдёно совпадение, программа напролом будет выполнять все действия до break, независимо: есть совпадение дальше или нет.
Но несмотря на всё это, у if-else есть пара преимуществ.
Например в булевой логике. Вот две равносильные записи
if(a<b)//предполагается, что а и b уже объявлены
{
//
}
else
{
//
}
и
switch(a<b)
{
case true: //
break;
case false: //
break;
}
Производительнее и понятнее будет первая запись. Отсюда следует, что если выражение на множественную проверку может принимать только ture и false значения, то лучше (предпочтительнее) воспользоваться if-else.
Все операторы, имеющие тела (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, то сначала это число стоит занести в переменную.
Удачи!