Оператора с побочным действием
Простые операторы
Простой оператор представ
Perl является императивным языком
программирования: его программа состоит из последовательности операторов, определяющих
некоторые действия. Оператор — это завершенная инструкция интерпретатору
на выполнение определенного действия. Все операторы языка Perl делятся на простые
и составные. Простой оператор представляет собой выражение, возможно, снабженное
модификатором. Составной оператор определяется в терминах блоков.
Каждый оператор Perl имеет возвращаемое
значение. Для простого оператора — это значение вычисляемого в нем выражения,
для составного оператора — значение последнего вычисленного в нем оператора.
Операторы обрабатываются в той последовательности,
в которой они встречаются в программе. Однако среди множества допустимых операторов
языка Perl, есть группа операторов, которая изменяет последовательность выполнения
операторов в программе.
ляет собой любое выражение, завершенное
точкой с запятой «;». Символ точка с запятой обязателен. Он может
отсутствовать, только если простой оператор является последним оператором в
блоке, специальной синтаксической конструкции, о которой мы поговорим чуть-чуть
позже.
Основное назначение простого оператора
— вычисление выражения с побочным эффектом, который связан с изменением значения
некоторых переменных в выражении при его вычислении. Обычно он реализуется операциями
увеличения/уменьшения на единицу (++, —):
$п++; # Переменная $п увеличивается на единицу. —$п**2; # Переменная $п уменьшается
на единицу.
Никакие другие операции Perl не вызывают побочных эффектов в выражении, если
не считать операции присваивания (простое и составное), результатом вычисления
которой является изменение значения левого операнда. Вызовы функций также могут
приводить к побочным эффектам, но об этом подробнее мы расскажем в главе
11.
Простой оператор Perl может содержать выражение и без побочного эффекта. Все
равно он будет рассматриваться интерпретатором как допустимый оператор, не выполняющий
никакого действия, а только вычисляющий значение выражения. Однако если установлен
флаг (-w) отображения интерпретатором предупреждающих сообщений, то будет получено
сообщение о бесполезности использования соответствующей операции в void-контексте.
Например, при выполнении оператора
($n*$m)**4 + 6;
будет отображено сообщение
Useless use of addition in void context at D:PERLEXAMPLE3.PL line 4.
Отметим, что в сообщении упоминается о последней выполненной операции в выражении.
Замечание
Подобное сообщение будет отображаться,
даже если в сложном выражении присутствует операция, вызывающая побочный эффект.
Сообщение не отображается только в случае выражения, составленного из одних
операций уменьшения /увеличения, или выражения присваивания.
Читатель спросит, какой прок в
операторе, не выполняющем никакого действия. Его можно использовать для задания
возвращаемого пользовательской функцией значения. Забегая вперед, скажем, что
если в функции явно не указано в операторе return о возвращаемое значение, то
по умолчанию Perl считает таковым значение последнего вычисленного оператора.
Именно это обстоятельство и используется многими программистами для определения
возвращаемого значения:
sub raySub {
какие-то операторы condition == true ? «Успех» : «Провал»;
# Последний оператор
* ‘
Последний оператор функции mysub вычисляет операцию выбора, в которой второй
и третий операнды представлены просто строковыми литералами — выражениями без
побочного эффекта. Результат вычисления одного из них и является возвращаемым
значением функции.
Copyright © Realcoding.NET 2003-2007.
При перепечатке материалов ссылка на автора материала обязательна.
Сообщить об ошибке или написать письмо администрации
через форму контактов.
—
Главная / Программирование /
Основы программирования на С# 3.0: ядро языка / Тест 8
Упражнение 1:
Номер 1
В результате выполнения фрагмента кода
int p = 1, q = 2, r = 3;
p += q *= r-= p+q+r;
переменные p, q, r примут значения:
Ответ:
 (1) p = 1, q = 2, r = 6 
 (2) p = 6, q = 6, r = 6 
 (3) p = -5, q = -6, r = -3 
 (4) p = 5, q = 6, r = 3 
Номер 2
К выражениям с побочным эффектом относятся выражения, заданные операциями:
Ответ:
 (1) присваивания (x = expr, x += y *= expr) 
 (2) увеличения и уменьшения (x++, x—, ++x, —x) 
 (3) арифметическими (x + y, x / y) 
 (4) сдвига (x << n, x >> n) 
Номер 3
Выражением с побочным эффектом называется выражение, которое помимо прямого эффекта — вычисления значения и типа выражения:
Ответ:
 (1) изменяет стандартный приоритет выполнения операций 
 (2) случайным образом изменяет значение выражения 
 (3) изменяет значение некоторой переменной, связанной с выражением 
 (4) изменяет тип операндов 
Упражнение 2:
Номер 1
Присваивание является ссылочным присваиванием, если:
Ответ:
 (1) источник присваивания относится к ссылочному типу, а тип цели может быть любым 
 (2) цель присваивания относится к ссылочному типу, а тип источника может быть любым 
 (3) ни цель, ни источник присваивания не относятся к ссылочному типу 
Номер 2
Отметьте истинные высказывания:
Ответ:
 (1) операции «упаковать» и «распаковать» (boxing, unboxing) выполняются, когда цель и источник присваивания относятся к разным типам — ссылочным и значимым 
 (2) переменной ссылочного типа нельзя присвоить значение выражения значимого типа 
 (3) любой переменной ссылочного типа можно присвоить значение выражения значимого типа 
 (4) переменной ссылочного типа object можно присвоить значение выражения значимого типа 
Номер 3
Присваивание является значимым присваиванием, если:
Ответ:
 (1) цель присваивания относится к значимому типу, а тип источника может быть любым 
 (2) источник присваивания относится к значимому типу, а тип цели может быть любым 
 (3) ни цель, ни источник присваивания не относятся к значимому типу 
Упражнение 3:
Номер 1
При выполнении фрагмента кода
for (int i = 0, j =1; i < 2; i++)
{
i—; j = -j;
}
Ответ:
 (1) возникнет ошибка на этапе компиляции 
 (2) возникнет ошибка на этапе выполнения 
 (3) при выполнении произойдет зацикливание 
 (4) ошибки не возникнет, и переменная j будет иметь значение 1 
 (5) ошибки не возникнет, и переменная j будет иметь значение -1 
Номер 2
Правда ли, что при выполнении фрагмента кода
int j = 0;
for (int i = 1; i < 5; i++)
{
if (i < 2) continue;
j += 2;
if (i < j) break;
}
Ответ:
 (1) возникнет ошибка на этапе компиляции 
 (2) возникнет ошибка на этапе выполнения 
 (3) при выполнении произойдет зацикливание 
 (4) ошибки не возникнет, и переменная j будет иметь значение 0 
 (5) ошибки не возникнет, и переменная j будет иметь значение 2 
 (6) ошибки не возникнет, и переменная j будет иметь значение 4 
 (7) ошибки не возникнет, и переменная j будет иметь значение 8 
Номер 3
При выполнении фрагмента кода
object x = 2+3;
Ответ:
 (1) возникнет ошибка на этапе компиляции 
 (2) возникнет ошибка на этапе выполнения 
 (3) ошибки не возникнет, и переменная x будет иметь значение 5 и тип object 
 (4) ошибки не возникнет, и переменная x будет иметь значение 5 и тип int 
Упражнение 4:
Номер 1
Отметьте истинные высказывания:
Ответ:
 (1) счетчик цикла в операторе цикла for можно изменять в теле цикла, но это может приводить к зацикливанию и другим серьезным ошибкам в момент выполнения 
 (2) изменение счетчика цикла в теле оператора цикла for приводит к ошибке, обнаруживаемой на этапе компиляции 
 (3) счетчик цикла может быть объявлен в заголовке оператора цикла for 
Номер 2
Какие из операторов не относятся к операторам перехода:
Ответ:
 (1) goto; 
 (2) break; 
 (3) switch; 
 (4) continue; 
 (5) return; 
Номер 3
Отметьте истинные высказывания:
Ответ:
 (1) оператор return, позволяет завершить выполнение процедуры или функции 
 (2) оператор break завершает выполнение цикла 
 (3) оператор continue завершает выполнение цикла 
 (4) оператор continue используется только в теле цикла 
Упражнение 5:
Номер 1
Отметьте истинные высказывания:
Ответ:
 (1) тело цикла foreach выполняется столько раз, сколько элементов находится в контейнере 
 (2) оператор yield позволяет заполнить контейнер элементами 
 (3) для всех видов цикла тело цикла выполняется хотя бы один раз 
Номер 2
Отметьте истинные высказывания:
Ответ:
 (1) присваивание является операцией языка C# 
 (2) в теле оператора foreach текущий элемент позволяет получать и изменять значения элементов, хранящихся в контейнере 
 (3) в операторе if число ключевых слов if должно совпадать с числом слов else 
 (4) case-выражение в операторе switch может задавать диапазон значений 
Номер 3
Операторами цикла в C# являются:
Ответ:
 (1) оператор for 
 (2) оператор foreach 
 (3) оператор while с проверкой условия в начале цикла 
 (4) оператор do — while с проверкой условия в конце цикла 
 (5) оператор loop с проверкой условия в середине цикла 
Упражнение 6:
Номер 1
Отметьте истинные высказывания:
Ответ:
 (1) любое выражение может использоваться в качестве оператора 
 (2) оператор if может быть эквивалентен по своему действию пустому оператору 
 (3) оператор foreach не применим при работе с массивами 
 (4) каждая case-ветвь оператора switch должна заканчиваться оператором break 
Номер 2
В результате выполнения следующего фрагмента кода
int a = 2, b = 3, c = 5, x = 0;
if( a > b)
if(c > a) if(c > a + b) x = a + b + c; else x = 7; else x = 12;
переменная x получит значение:
Ответ:
 (1) 0 
 (2) 7 
 (3) 10 
 (4) 12 
Номер 3
При выполнении фрагмента кода
int j = 0;
for (int i = 1; i < 5; i++)
{
if (i < 2) continue;
j += 2;
if (i < j) break;
}
Ответ:
 (1) возникнет ошибка на этапе компиляции 
 (2) тело цикла выполнится два раза 
 (3) тело цикла выполнится три раза 
 (4) тело цикла выполнится четыре раза 
Упражнение 7:
Номер 1
Правда ли, что при выполнении фрагмента кода
int j = 0;
for (byte i = 1; i > 0; i++) j = i;
Ответ:
 (1) возникнет ошибка на этапе компиляции 
 (2) возникнет ошибка на этапе выполнения 
 (3) при выполнении произойдет зацикливание 
 (4) ошибки не возникнет, и переменная j будет иметь значение 0 
 (5) ошибки не возникнет, и переменная j будет иметь значение 128 
 (6) ошибки не возникнет, и переменная j будет иметь значение 255 
Номер 2
Отметьте истинные высказывания:
Ответ:
 (1) выражения с побочным эффектом могут использоваться в качестве оператора 
 (2) оператор switch по своему действию может быть эквивалентен пустому оператору 
 (3) в заголовке операторе цикла for всегда требуется объявлять переменную, задающую счетчик цикла 
 (4) в теле оператора foreach не допускается присваивание значения текущему элементу 
Номер 3
Отметьте истинные высказывания:
Ответ:
 (1) выражения с побочным эффектом могут использоваться в качестве оператора 
 (2) оператор switch по своему действию может быть эквивалентен пустому оператору 
 (3) в заголовке операторе цикла for всегда требуется объявлять переменную, задающую счетчик цикла 
 (4) в теле оператора foreach не допускается присваивание значения текущему элементу 
Аннотация: Рассмотрен весь набор операторов языка С#. Обсуждаются их достоинства и недостатки. Операторы присваивания выбора и циклов составляют основу процесса алгоритмизации. Рассмотрены специальные операторы языка try — catch – finally, позволяющие организовать обработку исключительных ситуаций. Рассмотрен оператор yield, используемый в итераторах. Обсуждается тема математической бесконечности и конечности вычислений. Рассматриваются классические алгоритмы и даются задачи на эту тему.
Проект к данной лекции Вы можете скачать здесь.
Состав операторов языка C#, их синтаксис и семантика унаследованы от языка С++. Как и положено, потомок частично дополнил состав, переопределил синтаксис и семантику отдельных операторов, постарался улучшить характеристики языка во благо программиста. Посмотрим, насколько это удалось языку C#.
Оператор присваивания
В
«Выражения и операции»
подробно рассматривались операция и выражение присваивания
и многочисленные вариации, позволяющие строить выражения вида:
Синтаксически присваивание состоит из левой и правой частей, разделенных знаком операции присваивания. Правая часть — это выражение, в том числе выражение присваивания, как в последнем примере. Левая часть — это переменная; более точно: левая часть представляет собой lvalue — выражение левой части, которому можно присвоить значение. Переменная является наиболее распространенным частным случаем lvalue.
Выражение присваивания представляет собой пример выражения с побочным эффектом. Прямым эффектом вычисления такого выражения является вычисленное значение и тип выражения expr. Побочным эффектом является присваивание вычисленного значения переменной левой части.
Выражение с побочным эффектом в языке C# можно легко преобразовать в соответствующий оператор. Стоит такое выражение закончить символом точка с запятой, как получится оператор, который можно использовать всюду, где синтаксически допустимы операторы языка. Так что синтаксически оператор присваивания выглядит так:
Допустимы и многочисленные вариации:
К операторам присваивания можно отнести и такие операторы, как:
Эти операторы получены из соответствующих выражений с побочным эффектом — приписыванием в конце символа точки с запятой. Когда выражения с побочным эффектом преобразуются в операторы, побочный эффект занимает подобающее ему место и задает семантику оператора, а вычисление значения выражения становится частью процесса выполнения оператора.
Семантика присваивания
Казалось бы, семантика присваивания проста и очевидна — вычисляем выражение правой части и его значение присваиваем соответствующей переменной левой части. Но это лишь общее описание семантики. Детали значительно сложнее. Дело в том, что левая и правая часть имеют свои типы, и эти типы могут не совпадать. В этом случае необходимо выполнить преобразование типа правой части к типу левой части. Иногда такое преобразование безопасно, и его можно выполнить автоматически. Иногда такое преобразование опасно, и тогда возникнет ошибка, которая чаще всего обнаруживается еще на этапе компиляции.
Будем называть целью левую часть оператора присваивания, а источником — правую часть оператора присваивания. Источник и цель могут быть как значимого, так и ссылочного типа. Присваивание будем называть ссылочным, если цель ссылочного типа. В этом случае источник должен быть ссылочного типа или быть приведенным к этому типу. Присваивание будем называть значимым, если цель значимого типа. В этом случае источник должен быть значимого типа или быть приведенным к этому типу.
Операции «упаковать» и «распаковать» — boxing и unboxing
Возникает естественный вопрос: можно ли ссылочным переменным, связанным с объектами, хранимыми в куче, присваивать значимые переменные, хранимые в стеке? Можно ли выполнять обратную операцию? В C# такие возможности преобразования типов предусмотрены. Операция «упаковать» ( boxing ) позволяет переменную значимого типа «упаковать в одежды класса», создавая объект в динамической памяти. Такое преобразование выполняется автоматически всякий раз, когда цель принадлежит классу object, а источником может быть переменная любого из значимых типов. Операция «распаковать» ( unboxing ) позволяет переменную типа object «распаковать и извлечь хранимое значение». Такое преобразование выполняется автоматически. Извлеченное значение не сохраняет информацию о своем типе. Поэтому, прежде чем присвоить это значение цели, его необходимо привести к нужному типу. Ответственность за это приведение лежит на программисте.
Рассмотрим подробнее, какие преобразования могут выполняться в процессе присваивания.
Цель и источник значимого типа. Здесь речь идет о семантике значимого присваивания. В этом случае источник и цель имеют собственную память для хранения значений. Если типы цели и источника совпадают, то никаких проблем нет. Значения источника копируются и заменяют значения соответствующих полей цели. Источник и цель после этого продолжают жить независимо. У них своя память, хранящая после присваивания одинаковые значения. Если типы разные, то необходимо преобразование типов. Оно может быть безопасным и тогда выполняется автоматически. В противном случае оно должно явно задаваться программистом. Явные и неявные преобразования внутри арифметического типа, кастинг, метод Parse и методы класса Convert подробно рассматривались в
«Типы и классы. Переменные и объекты»
.
Цель и источник ссылочного типа. Здесь имеет место семантика ссылочного присваивания — присваивание ссылок. В этом случае значениями источника и цели являются ссылки на объекты, хранящиеся в динамической памяти («куче»). Если типы источника и цели совпадают, то никаких проблем нет. Цель разрывает связь с тем объектом, на который она ссылалась до присваивания, и становится ссылкой на объект, связанный с источником. Результат ссылочного присваивания двоякий. Объект, на который ссылалась цель, теряет одну из своих ссылок и может стать «висячим» — бесполезным объектом, на который никто не ссылается, так что его дальнейшую судьбу определит сборщик мусора.
После присваивания с объектом в памяти, на который ссылался источник, теперь связываются, по меньшей мере, две ссылки, рассматриваемые как различные имена одного объекта. Ссылочное присваивание приводит к созданию псевдонимов — к появлению разных имен у одного объекта. Особо следует учитывать ситуацию, когда цель и/или источник имеет значение null — нулевой ссылки, не указывающей ни на какой объект. Если такое значение имеет источник, то в результате присваивания цель получает это значение и более не ссылается ни на какой объект. Если же цель имела значение null, а источник — нет, то в результате присваивания ранее «висячая» цель становится ссылкой на объект, связанный с источником.
Если типы источника и цели разные, то присваивание без всяких преобразований возможно лишь в том случае, если источник является потомком родительского класса, заданного целью. Цель-родитель может быть связана с объектом своего потомка, поскольку в этом случае все поля и методы родителя имеются и у потомка и будут определены.
Если же цель не принадлежит родительскому классу источника, то тогда ссылочное присваивание возможно лишь при условии явного задания приведения типов, но тогда вся ответственность за успех этого преобразования лежит на программисте, который должен быть уверен, что объект источника, связанный ссылкой, действительно принадлежит классу целевого объекта.
Цель ссылочного типа, источник значимого типа. В этом случае «на лету» значимый тип преобразуется в ссылочный. Как обеспечивается двойственность существования значимого и ссылочного типа — переменной и объекта? Ответ прост: за счет эффективно реализованной операции «упаковать» ( boxing ), выполняемой автоматически.
Такое присваивание возможно лишь в том случае, когда цель принадлежит классу object. Поскольку класс object является родителем для всех классов, в том числе и для значимых классов, при таком присваивании никаких ошибок возникать не будет, оно всегда возможно.
Цель значимого типа, источник ссылочного типа. В этом случае «на лету» ссылочный тип преобразуется в значимый. Операция «распаковать» ( unboxing ) выполняет обратную операцию — она «сдирает» объектную упаковку и извлекает хранимое значение. Заметьте, операция «распаковать» не является обратной к операции «упаковать» в строгом смысле этого слова. Оператор object obj = x корректен, но выполняемый следом оператор x = obj приведет к ошибке. Недостаточно, чтобы хранимое значение в упакованном объекте точно совпадало по типу с переменной, которой присваивается объект. Необходимо явно заданное преобразование к нужному типу.
Блок, или составной оператор
С помощью фигурных скобок несколько операторов языка (возможно, перемежаемых объявлениями) можно объединить в единую синтаксическую конструкцию, называемую блоком или составным оператором:
оператор_1
…
оператор_N
}
В языках программирования нет общепринятой нормы для использования символа точки с запятой при записи последовательности операторов. Есть три различных подхода и их вариации. Категорические противники точек с запятой считают, что каждый оператор должен записываться на отдельной строке (для длинных операторов определяются правила переноса). В этом случае точки с запятой (или другие аналогичные разделители) не нужны. Горячие поклонники точек с запятой (к ним относятся авторы языков С++ и C#) считают, что точкой с запятой должен оканчиваться каждый оператор. В результате в операторе if перед else появляется точка с запятой. Третьи полагают, что точка с запятой не принадлежит оператору, а играет роль разделителя операторов. В выше приведенной записи блока, следуя синтаксису C#, каждый из операторов заканчивается символом точка с запятой. Но, заметьте, блок не заканчивается этим символом!
Синтаксически блок воспринимается как единичный оператор и может использоваться всюду в конструкциях, где синтаксис требует одного оператора. Тело цикла, ветви оператора if, как правило, представляются блоком.
Пустой оператор
Пустой оператор — это «пусто», завершаемое точкой с запятой. Иногда полезно рассматривать отсутствие операторов как существующий пустой оператор. Вот пример:
else
{
int temp = a; a = b; b = temp;
}
Это корректно работающий пример. А вот типичная для новичков ошибка:
{
…
}
Здесь телом цикла является пустой оператор.
Операторы выбора
Как в С++ и других языках программирования, в языке C# для выбора одной из нескольких возможностей используются две конструкции — if и switch. Первую из них обычно называют альтернативным выбором, вторую — разбором случаев.
Оператор if
Начнем с синтаксиса оператора if:
else if(выражение_2) оператор_2
…
else if(выражение_K) оператор_K
else оператор_N
Какие особенности синтаксиса следует отметить? Логические выражения if заключаются в круглые скобки и имеют значения true или false. Каждый из операторов может быть блоком, в частности, if -оператором. Поэтому возможна и такая конструкция:
Ветви else if, позволяющие организовать выбор из многих возможностей, могут отсутствовать. Может быть опущена и заключительная else -ветвь. В этом случае краткая форма оператора if задает альтернативный выбор — делать или не делать — выполнять или не выполнять then -оператор.
Семантика оператора if проста и понятна. Выражения if проверяются в порядке их написания. Как только получено значение true, проверка прекращается и выполняется оператор (это может быть блок), который следует за выражением, получившим значение true. С завершением этого оператора завершается и оператор if. Ветвь else, если она есть, относится к ближайшему открытому if.
Оператор switch
Частным, но важным случаем выбора из нескольких вариантов является ситуация, при которой выбор варианта определяется значениями некоторого выражения. Соответствующий оператор C#, унаследованный от C++, но с небольшими изменениями в синтаксисе, называется оператором switch. Вот его синтаксис:
{
case константное_выражение_1: [операторы_1 оператор_перехода_1]
…
case константное_выражение_K: [операторы_K оператор_перехода_K]
[default: операторы_N оператор_перехода_N]
}
Ветвь default может отсутствовать. Заметьте: по синтаксису допустимо, чтобы после двоеточия следовала пустая последовательность операторов, а не последовательность, заканчивающаяся оператором перехода. Константные выражения в case должны иметь тот же тип, что и switch -выражение.
Семантика оператора switch чуть запутана. Вначале вычисляется значение switch -выражения. Затем оно поочередно в порядке следования case сравнивается на совпадение с константными выражениями. Как только достигнуто совпадение, выполняется соответствующая последовательность операторов case -ветви. Поскольку последний оператор этой последовательности является оператором перехода (чаще всего это оператор break ), обычно он завершает выполнение оператора switch. Использование операторов перехода — это плохая идея. Таким оператором может быть оператор goto, передающий управление другой case -ветви, которая, в свою очередь, может передать управление еще куда-нибудь, получая блюдо «спагетти» вместо хорошо структурированной последовательности операторов. Семантика осложняется еще и тем, что case -ветвь может быть пустой последовательностью операторов.
Тогда в случае совпадения константного выражения этой ветви со значением switch -выражения будет выполняться первая непустая последовательность очередной case -ветви. Если значение switch -выражения не совпадает ни с одним константным выражением, то выполняется последовательность операторов ветви default, если же таковой ветви нет, то оператор switch эквивалентен пустому оператору.
Полагаю, что оператор switch — это самый неудачный оператор языка C# как с точки зрения синтаксиса, так и семантики. Неудачный синтаксис порождает запутанную семантику, являющуюся источником плохого стиля программирования. Понять, почему авторов постигла неудача, можно, оправдать — нет. Дело в том, что оператор унаследован от С++, где его семантика и синтаксис еще хуже. В языке C# синтаксически каждая case-ветвь должна заканчиваться оператором перехода (забудем на минуту о пустой последовательности), иначе возникнет ошибка периода компиляции. В языке С++ это правило не является синтаксически обязательным, хотя на практике применяется та же конструкция с конечным оператором break. При его отсутствии управление «проваливается» в следующую case-ветвь. Конечно, профессионал может с успехом использовать этот трюк, но в целом ни к чему хорошему это не приводит.
Борясь с этим, в C# потребовали обязательного включения оператора перехода, завершающего ветвь. Гораздо лучше было бы, если бы последним оператором мог быть только оператор break, как следствие, его можно было бы не писать, и семантика стала бы прозрачной — при совпадении значений двух выражений выполняются операторы соответствующей case-ветви, при завершении которой завершается и оператор switch.
Еще одна неудача в синтаксической конструкции switch связана с существенным ограничением, накладываемым на case-выражения, которые могут быть только константным выражением. Уж если изменять оператор, то гораздо лучше было бы использовать синтаксис и семантику Visual Basic, где в case-выражениях допускается список, каждое из выражений которого может задавать диапазон значений.
Разбор случаев — это часто встречающаяся ситуация в самых разных задачах. Применяя оператор switch, помните о недостатках его синтаксиса, используйте его в правильном стиле. Заканчивайте каждую case-ветвь оператором break, но не применяйте goto.
Содержательный пример применения оператора switch подробно рассмотрен в
«Типы и классы. Переменные и объекты»
. Рассмотрим еще один показательный пример, в котором вычисляется арифметическое выражение с двумя аргументами.
/// Разбор случаев с использованием списков выражений
/// </summary>
/// <param name=»operation»>операция над аргументами</param>
/// <param name=»arg1″>первый аргумент бинарной операции</param>
/// <param name=»arg2″>второй аргумент бинарной операции</param>
/// <param name=»result»>результат бинарной операции</param>
public void ExprResult(string operation, double arg1, double arg2,
ref double result)
{
switch (operation)
{
case «+»:
case «Plus»:
case «Плюс»:
result = arg1 + arg2;
break;
case «-«:
case «Minus»:
case «Минус»:
result = arg1 — arg2;
break;
case «*»:
case «Mult»:
case «Умножить»:
result = arg1 * arg2;
break;
case «/»:
case «Divide»:
case «Div»:
case «разделить»:
case «Делить»:
result = arg1 / arg2;
break;
default:
result = 0;
break;
}
}//ExprResult
Обратите внимание: знак операции над аргументами можно задавать разными способами, что демонстрирует возможность задания списка константных выражений в ветвях оператора switch.