Читать в оригинале

<< ПредыдущаяОглавлениеСледующая >>


5.4. Операторы выбора

Как в С++ и других языках программирования, в языке C# для выбора одной из нескольких возможностей используются две конструкции - if и switch. Первую из них обычно называют альтернативным выбором, вторую - разбором случаев.

5.4.1. Оператор if

Начнем с синтаксиса оператора if:

if (выражение_1)
оператор_1
else if (выражение_2)
оператор_2

else if (выражение_К)
оператор_К
else оператор_N

Следует отметить следующую особенность синтаксиса: выражения if должны заключаться в круглые скобки и быть булевого типа. Точнее, выражения должны давать значения true или false. По правилам синтаксиса языка С++, then-ветвь оператора следует сразу за круглой скобкой без ключевого слова then, типичного для большинства языков программирования. Каждый из операторов может быть блоком - в частности, if-оператором. Поэтому возможна и такая конструкция:

if (выражение1) if (выражение2) if (выражение3) ...

Ветви else и if, позволяющие организовать выбор из многих возможностей, могут отсутствовать. Может быть опущена и заключительная else-ветвь. В этом случае краткая форма оператора if задает альтернативный выбор - делать или не делать - выполнять или не выполнять then-оператор.

Выражения if проверяются в порядке их написания. Как только получено значение true, проверка прекращается и выполняется оператор (это может быть блок), который следует за выражением, получившим значение true. С завершением этого оператора завершается и оператор if. Ветвь else, если она есть, относится к ближайшему открытому if.

 

5.4.2. Оператор switch

Частным, но важным случаем выбора из нескольких вариантов является ситуация, при которой выбор варианта определяется значениями некоторого выражения. Соответствующий оператор C#, унаследованный от C++, но с небольшими изменениями в синтаксисе, называется оператором switch.

Вот его синтаксис:

switch(выражение) {
case константное_выражение_1: [операторы_1]; break;

case константное_выражение_К: [операторы_К]; break;
[default: операторы_N оператор_перехода_N break;]
}

Ветвь default может отсутствовать. Отметим, по синтаксису допустимо, чтобы после двоеточия следовала пустая последовательность операторов, а не последовательность, заканчивающаяся оператором перехода. Константные выражения в case должны иметь тот же тип, что и switch-выражение.

Семантика оператора switch чуть запутана. Вначале вычисляется значение switch-выражения. Затем оно поочередно в порядке следования предложений case сравнивается на совпадение с константными выражениями. Как только достигнуто совпадение, выполняется соответствующая последовательность операторов case-ветви. Поскольку последний оператор этой последовательности является оператором перехода (чаще всего это оператор break), то обычно он завершает выполнение оператора switch. Таким оператором может быть оператор goto, передающий управление другой case- ветви, которая, в свою очередь, может передать управление еще куда-нибудь, нарушая хорошо структурированную последовательность операторов. Семантика осложняется еще и тем, что case-ветвь может быть пустой последовательностью операторов. Тогда в случае совпадения константного выражения этой ветви со значением switch-выражения будет выполняться первая непустая последовательность очередной case-ветви. Если значение switch-выражения не совпадает ни с одним константным выражением, то выполняется последовательность операторов ветви default, если же таковой ветви нет, то оператор switch эквивалентен пустому оператору. Case-выражения могут быть только константным выражением.

Разбор случаев - это часто встречающаяся ситуация в самых разных задачах.

Когда разбор случаев предполагает проверку попадания в некоторый диапазон значений, приходится прибегать к оператору if для формирования специальной переменной.

Этот прием демонстрируется в следующем примере, где идет работа над данными нашего класса Testing:

/// <summary>
/// Определяет период в зависимости от возраста - age
/// Использование ветвящегося оператора if
/// </summary>
public void SetPeriod() {
          if ((age > 0) && (age < 7))
            period = 1;
          else if ((age >= 7) && (age < 17))
            period = 2;
          else if ((age >= 17) && (age < 22))
            period = 3;
          else if ((age >= 22) && (age < 27))
            period = 4;
          else if ((age >= 27) && (age < 37))
            period = 5;
          else period = 6;
}

Этот пример демонстрирует применение ветвящегося оператора if. С содержательной точки зрения он интересен тем, что в поля класса пришлось ввести специальную переменную period, позволяющую в дальнейшем использовать разбор случаев в зависимости от периода жизни:

/// <summary>
/// Определяет статус в зависимости от периода - period
/// Использование разбора случаев - оператора Switch
/// </summary>
public void SetStatus() {
          switch (period) {
          case 1:
            status = "child"; break;
          case 2:
            status = "schoolboy"; break;
          case 3:
            status = "student"; break;
          case 4:
            status = "junior researcher"; break;
          case 5:
            status = "senior researcher"; break;
          case 6:
            status = "professor"; break;
          default:
            status = "не определен"; break;
          }
          Console.WriteLine("Имя = {0}, Возраст = {1}, Статус = {2}", name, age, status);
} //SetStatus

Этот пример демонстрирует корректный стиль использования оператора switch. В следующем примере показана роль пустых последовательностей операторов case-ветвей для организации списка выражений одного варианта:

/// <summary>
/// Разбор случаев с использованием списков выражений
/// </summary>
/// <param name="operation"> операция над аргументами</param>
/// <param name="arg1"> первый аргумент бинарной операции</param>
/// <param name="arg2"> второй аргумент бинарной операции</param>
/// <param name="result"> результат бинарной операции</param>
public void ExprResult(string operation, int arg1, int arg2, ref int 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;
            Console.WriteLine("Операция не определена");
            break;
}
Console.WriteLine("{0} ({1}, {2}) = {3}", operation, arg1, arg2, result);
} //ExprResult

 



<< ПредыдущаяОглавлениеСледующая >>