Операторы ветвления

Лабораторная работа № 2.

Операторы языка C#

Программы на языке C# состоят из последовательности операторов. Оператор – это законченное описание некоторого действия, заканчивающееся точкой с запятой. Выделим четыре группы операторов: операторы следования, операторы ветвления, операторы цикла и операторы передачи управления.

 

Операторы следования

Операторы следования выполняются компилятором в линейном порядке, последовательно один за другим.

Примеры операторов:

 

a = b; //оператор присваивания

++i; //оператор инкремента

Console.WriteLine(i); //оператор - вызов метода

m = Math.Min(a, b) + 5; //вычисление выражения

 

Частным случаем оператора является доступный в языке C# пустой оператор:

;

 

Он используется тогда, когда по синтаксису оператор требуется, а по смыслу – нет. В большинстве случаев пустые операторы можно вставлять в программу, и такая вставка не вызовет ошибок, однако это не всегда безопасно. В частности, если случайно вставить точку с запятой после условия оператора if или while, работа ветвления или цикла может совершенно поменяться. В связи с этим пустые операторы лучше не использовать.

Еще одним вариантом оператора является блок или составной оператор. Он представляет собой последовательность операторов, заключенных в фигурные скобки.

 

{

<Оператор1>;

...

<ОператорN>;

}

 

Блок может содержать любое количество операторов, в том числе один или ни одного. Входящие в блок операторы могут и сами в свою очередь быть составными.

Заметьте, что хотя блок и считается оператором, точка с запятой после него не ставится.

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

Блок обладает собственной областью видимости: объявленные внутри блока переменные, константы, методы и т. п. доступны только внутри данного блока или блоков, вложенных в него.

Операторы ветвления

Операторы ветвления позволяют сделать порядок выполнения операторов в программе нелинейным. В зависимости от некоторого условия вычислительный процесс может пойти по одной или другой ветви. К операторам ветвления относятся условный оператор if и оператор выбора switch.

Кроме того, к операторам ветвления некоторые авторы относят и условную операцию, рассмотренную нами ранее (2.6.6).

 

string s = (i < 0) ? "Отрицательное число" : "Положительное число";

 

В зависимости от условия (i < 0) строковая переменная s принимает одно из двух значений. Например, если i = 5, то s присваивается значение “Положительное число”, а если i = –8, то переменная s становится равна “Отрицательное число”. С помощью условной операции сделать и более разветвленный вариант:

 

string s = (i < 0) ? "Отрицательное число" : (i > 0) ? "Положительное число" : "Нуль";

 

Здесь в зависимости от значения переменной i есть три варианта присваивания для переменной s – добавляется вариант для i = 0: s при этом становится равна “Нуль”.

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

Условный оператор if используется для разветвления процесса обработки данных. Он может иметь одну из форм: сокращенную или полную.

Синтаксис сокращенного (неполного) оператора if:

 

if (<Условие>) <Оператор>;

 

Здесь Условие – это выражение, истинность которого проверяется; Оператор может быть простым или составным. Условный оператор работает следующим образом – сначала вычисляется выражение в скобках, потом оно анализируется: если Условие == истина, то Оператор выполняется, если Условие ==ложь, то нет. Таким образом, с помощью сокращенной формы оператора if можно либо выполнить Оператор, либо пропустить его.

Синтаксис полной формы оператора if:

 

if (<Условие>) <Оператор1>; else <Оператор2>;

 

Здесь аналогично сокращенной форме оператора, Условие – это выражение, истинность которого проверяется; Оператор1 и Оператор2 могут быть простыми или составными. Работает полная форма if так: сначала вычисляется выражение в скобках, потом анализируется его результат: если Условие == истина, то выполняется Оператор1, а Оператор2 пропускается; если Условие == ложь, то выполняется Оператор2, а Оператор1 пропускается. Таким образом, с помощью полной формы оператора if можно выбрать одно из двух альтернативных действий процесса обработки данных.

Оператор1 и Оператор2 могут в свою очередь тоже являться условными операторами. Такие операторы называют вложенными, при этом ключевое слово else связывается с ближайшим предыдущим if, который еще не связан ни с одним else.

Приведем примеры, показывающие каким образом любую условную операцию можно переписать с помощью оператора if:

 

if (i < 0) s = "Отрицательное число"; else s = "Положительное число";

 

Вариант с тремя альтернативами:

 

if (i < 0) s = "Отрицательное число";

else if (i > 0) s = "Положительное число";

else s = "Нуль";

 

Рассмотрим еще несколько примеров записи условного оператора:

 

// Сокращенная форма c простым оператором

if (a == 0) a = 1;

 

// Сокращенная форма c составным оператором

if (a > b)

{

a = 2 * b;

b = 3 - a;

}

 

// Полная форма с простым оператором

if (a > 0 || b > 0) a = 1;

else a = -1;

 

// Полная форма с составными операторами

if (a + b <= 6)

{

a = 0;

b = 1;

}

else

{

a = 1;

b = 0;

}

Оператор выбора switch предназначен для разветвления процесса вычислений по нескольким направлениям. В отличие от оператора if, в switch выбор варианта определяется различными значениями некоторого одного выражения. В таких проверках разрешено использовать только дискретные значения.

Синтаксис оператора выбора switch (то, что записано в квадратных скобках, является необязательным элементом):

 

switch (<Выражение>)

{

case <КонстантноеВыражение1>: [<Оператор1>; <ОператорПерехода>;]

case <КонстантноеВыражение2>: [<Оператор2>; <ОператорПерехода>;]

...

case <КонстантноеВыражениеN>: [<Операторn>; <ОператорПерехода>;]

[default: <ОператорDefault>; <ОператорПерехода>;]

}

 

Оператор выбора выполняется следующим образом:

– сначала вычисляется выражение, расположенное за ключевым словом switch;

– полученный результат поочередно в порядке следования меток case сравнивается на совпадение с константными выражениями;

– как только будет найдено соответствующее результату константное выражение в некоторой метке case, выполнится оператор, стоящий после этой метки:

· оператор в любой ветке case может быть простым или составным, после него обязательно должен следовать оператор перехода(break, goto, return);

· если оператор в ветке case пустой, то и оператор перехода может отсутствовать;

· при использовании оператора break происходит выход из switch и управление передается первому оператору, следующему за switch, другие ветки case при этом пропускаются;

· если используется оператор goto, то управление передается оператору, помеченному меткой, стоящей после goto;

· если несколько меток case с константными выражениями перечислены через двоеточие, то следующие за этим операторы будут выполняться при совпадении switch-выражения с любым из этих константных выражений;

– если значение switch-выражения не совпадает ни с одним константным выражением, то выполняются операторы из ветви default.

Всегда используйте оператор break, поскольку другие операторы перехода могут сделать программы несоответствующей правильному стилю структурного программирования!

Отметим еще ряд особенностей оператора выбора:

– выражение, стоящее за ключевым словом switch, должно иметь арифметический, символьный, строковый тип или тип указатель;

– все константные выражения должны иметь разные значения, но их тип должен совпадать с типом switch-выражения или приводиться к нему;

– даже если в какой-либо ветке case должно выполняться несколько операторов, их, несмотря на то, что они являются составным оператором, необязательно объединять с помощью фигурных скобок в блок, признаком окончания ветки является оператор перехода;

– ветвь default может отсутствовать.

Далее рассмотрим пример использования оператора выбора switch.

 

Console.Write("Operation = ");

char operation = char.Parse(Console.ReadLine());

Console.Write("Operand1 = ");

int operand1 = int.Parse(Console.ReadLine());

Console.Write("Operand2 = ");

int operand2 = int.Parse(Console.ReadLine());

int result = 0; bool ok = true;

switch (operation)

{

case '+': result = operand1 + operand2; break;

case '-': result = operand1 - operand2; break;

case '*': result = operand1 * operand2; break;

case '/': case ':':

if (operand2 != 0)

{

result = operand1 / operand2; break;

}

else ok = false; break;

default: ok = false; break;

}

if (ok) Console.WriteLine(operand1 + " " + operation + " "

+ operand2 + " = " + result);

else Console.WriteLine("Error");

 

В этом примере по заданной арифметической операции (сложение, вычитание, умножение и деление) и двум операндам на экран выводится результат применения данной операции к операндам. Оператор switch анализирует значение переменной operation и выполняет над операндами действия в разных case. В ветках, соответствующих сложению, вычитанию и умножению, имеется всего один оператор, завершающийся break. В ветке, соответствующей делению, есть два варианта значения operation (: и /), при любом из них выполняются одинаковые действия: если второй операнд не равен нулю, то выполняется операция деления и вызывается break, в противном случае логической переменной присваивается значение false. На метку по умолчанию будет выполняться переход в случае, если введен неверный знак операции.