Смекни!
smekni.com

Основы алгоритмизации и программирования 2 (стр. 10 из 32)

else comparison = "greater than";

В заключение происходит вывод значения переменной comparison на консоль:

Console.WriteLine("The first number is {0} the second number.", comparison);

Использование вложенных операторов представляет собой лишь один из возможных путей решения этой задачи. С тем же успехом можно было бы написать следующее:

if (varl < var2) comparison = "less than";

if (varl = = var2) comparison = "equal to";

if (varl > var2) comparison = "greater than";

Недостатком такого способа является необходимость выполнять все три сравнения независимо от значений переменных varl и var2. В первом же случае выполняется только одно сравнение, если varl < var2 есть true, и два сравнения в противном случае (мы также выполняем сравнение varl = = var2), т. е. выполняется меньшее число строк кода. Разница в быстродействии несущественна, однако она может иметь значение для тех приложений, для которых скорость выполнения является критичной.

2.3.3.Проверка большего количества условий с помощью оператора if

В предыдущем примере проверялись три условия для значения переменной var1, которые охватывали все возможные для нее значения. Однако в некоторых случаях может потребоваться выполнять проверку на какие-то конкретные значения, например, 1,2, 3, 4 и т. д. Используя тот же подход, получим неудобоваримый вложенный код вроде:

if (varl = = 1) {

// выполнение каких-либо действий } else { if (varl = = 2) {

// выполнение каких-либо других действий > else {

if (varl = =31 || varl = = 4) {

// выполнение каких-либо других действий > else {

// выполнение каких-либо других действий }

}

}

Существует очень распространенная ошибка, когда условие в третьем сравнении записывается как if (var1 = = 3 || 4). В таком случае в полном соответствии со старшинством операторов сначала будет выполнен оператор = =, в результате чего оператор || будет выполняться с операндами логического и численного типов. Это приведет к ошибке.

В такой ситуации разумнее применить несколько иную систему отступов и объединения элементов кода для блоков else (т. е. использовать после блока else одну строку кода, а не целый блок кода). Если поступить таким образом, то получим следующую структуру, содержащую операторы else if:

if (varl = = 1) {

// выполнение каких-либо действий }

else if (varl = = 2) {

// выполнение каких-либо других действий }

else if (varl = = 3 || varl = = 4) {

// выполнение каких-либо других действий } else {

// выполнение каких-либо других действий }

На самом деле операторы else if представляют собой два отдельных оператора, и вышеприведенный код идентичен первоначальному варианту. Однако такой код является более удобочитаемым.

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

2.3.4.Оператор switch

Оператор switch очень похож на оператор if в том смысле, что он также обеспечивает условное выполнение кода в зависимости от результата выполненной проверки. Однако оператор switch позволяет производить проверку для многих значений переменной за один проход вместо того, чтобы проверять всего лишь одно условие. Эти проверки ограничены отдельными значениями и не допускают конструкций типа "больше, чем X", поэтому их использование имеет некоторые отличия; однако такой способ является очень эффективным.

Принципиальная структура оператора switch имеет следующий вид. switch (<контрольнаяПеременная>)

{ case <значение1>:

<код, который должен выполняться в том случае, если <контрольнаяПеременная> = = <значение1> > break;

case <значение2>:

<код, который должен выполняться в том случае, если <контрольнаяПеременная> = = <значение2> > break;

case <значениеN>:

<код, который должен выполняться в том случае, если <контрольнаяПеременная> = = <значениеN> > break;

default:

<код, который должен выполняться в том случае, если <контрольнаяПеременная> != ни одному из значений>> break; }

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

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

Оператор break в данном случае просто прерывает выполнение оператора switch, и работа программы продолжается со следующего оператора

В программе на С# имеются и другие способы избежать передачи управления от одного оператора case другому. Мы можем использовать либо оператор return, который приведет к прерыванию выполнения текущей функции, а не просто оператора switch, либо оператор goto. Оператор goto (он описан выше) в данном случае будет работать, поскольку операторы case в программе на С# фактически выполняют роль меток.

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

Эти условия также относятся и к оператору default. Не существует никакого правила, требующего, чтобы этот оператор обязательно находился в конце всего перечня сравнений, и при желании мы можем объединять его с операторами case. Включение оператора, прерывающего нормальное выполнение программы - break, goto или return,гарантирует правильную последовательность выполняемых действий в любом случае.

Все переменные <значениех>, использующиеся для сравнений, должны иметь постоянное значение. Один из способом добиться этого - применение литеральных значений:

switch (myInteger) { case 1:

<код, который должен выполняться в том случае, если myInteger = = 1 > break; case -1:

<код, который должен выполняться в том случае, если myInteger = = -1 > break; default:

<код, который должен выполняться в том случае, если myInteger != ни одному из значений, использовавшихся для сравнения> break; }

Другой способ получить постоянные значения переменных – это использование переменных-констант. Переменные-константы являются точно такими же переменными, как и все остальные, за исключением одного ключевого момента: значение, которое в них содержится, не может быть изменено ни при каких условиях. После того как присвоить переменной-константе какое-либо значение, оно будет оставаться неизменным на протяжении выполнения всей программы. Переменные-константы могут оказаться удобными в данном случае, поскольку зачастую код легче понимать, когда используемые для сравнения значения не видны в момент выполнения сравнения.

Можно объявить переменную-константу, добавив ключевое слово const к описанию типа переменной; при этом требуется сразу определить ее значение. Например:

const int intTwo =2; '

Этот код является вполне допустимым, однако если попытаться выполнить следующий код:

const int intTwo;
intTwo =2;

то получим сообщение об ошибке на этапе компиляции. Также приведет к ошибке и попытка каким-либо образом изменить содержимое переменной-константы после первоначального присваивания.

2.4.Организация циклов

Цикл – это участок кода, в котором операторы выполняются по несколько раз. Такой способ в ряде случаев бывает чрезвычайно удобным, поскольку позволяет повторять необходимые действия столько раз, сколько требуется (тысячи и даже миллионы), без необходимости выписывать соответствующий код такое же количество раз.

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

double balance = 1000;

double interestRate =1.05; //5% годовых
balance *= interestRate; balance *= interestRate; balance *= interestRate; balance *= interestRate; balance *= interestRate; balance *= interestRate; balance *= interestRate; balance *= interestRate; balance *= interestRate; balance *= interestRate;

Выписывать один и тот же код 10 раз весьма расточительно, и потом, как быть, если потребуется изменить срок с 10 лет на другое значение? Придется вручную копировать строку с кодом необходимое число раз, что добавит немало головной боли!

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

Другой тип цикла – это цикл, вычисления в котором продолжаются до тех пор, пока не будет выполнено определенное условие. Такие циклы несколько проще (хотя не менее полезны), чем описанные выше, поэтому мы с них и начнем.

2.4.1.Цикл do

Цикл do работает следующим образом. Код, который помечен как выполняющийся в цикле, выполняется первый раз, затем проверяется некоторое логическое условие, и если результат равен true, то этот код выполняется еще раз, и т. д.