1629295407-c61bfe4caba98380ea3e7cdae6295416 (846200), страница 21
Текст из файла (страница 21)
Ее можно представить вследующем виде:if(условие)инструкция;else if(условие)инструкция;else if(условие)инструкция;...elseинструкция;Здесь под элементом условие понимается условное выражение. Условныевыражения вычисляются сверху вниз. Как только в какой-нибудь ветви обнаружитсяистинный результат, будет выполнена инструкция, связанная с этой ветвью, а вся остальная“лестница” опускается. Если окажется, что ни одно из условий не является истинным, будетвыполнена последняя else-инструкция (можно считать, что она выполняет роль условия,которое действует по умолчанию). Если последняя else-инструкция не задана, а всеостальные оказались ложными, то вообще никакое действие не будет выполнено.Работа if-else-if-“лестницы” демонстрируется в следующей программе, котораянаходит для заданного значения наименьший множитель {отличный от единицы исостоящий из одной цифры).// Определение наименьшего множителя,// состоящего из одной цифры.using System;Глава 5.
Инструкции управления105class Ladder {public static void Main() {int num;for(num = 2; num < 12; num++) {if((num % 2) == 0)Console.WriteLine("Наименьший множитель числа " +num + " равен 2.");else if((num % 3) == 0)Console.WriteLine("Наименьший множитель числа " +num + " равен 3.");else if((num % 5) == 0)Console.WriteLine("Наименьший множитель числа " +num + " равен 5.");else if((num % 7) ==0)Console.WriteLine("Наименьший множитель числа " +num + " равен 7.");elseConsole.WriteLine(num +" не делится на 2, 3, 5 или 7.");}}}Результаты выполнения этой программы выглядят так:Наименьший множитель числа 2 равен 2.Наименьший множитель числа 3 равен 3.Наименьший множитель числа 4 равен 2.Наименьший множитель числа 5 равен 5.Наименьший множитель числа 6 равен 2.Наименьший множитель числа 7 равен 7.Наименьший множитель числа 8 равен 2.Наименьший множитель числа 9 равен 3.Наименьший множитель числа 10 равен 2.11 не делится на 2, 3, 5 или 7.Как видите, последняя else-инструкция выполняется только в том случае, если невыполнилась ни одна из предыдущих if-инструкций.Инструкция switchВторой инструкцией выбора является switch.
Инструкция switch обеспечиваетмногонаправленное ветвление. Она позволяет делать выбор одной из множестваальтернатив. Хотя многонаправленное тестирование можно реализовать с помощьюпоследовательности вложенных if-инструкций, для многих ситуаций инструкция switchоказывается более эффективным решением.
Она работает следующим образом. Значениевыражения последовательно сравнивается с константами из заданного списка. Приобнаружении совпадения для одного из условий сравнения выполняетсяпоследовательность инструкций, связанная с этим условием. Общий формат записиинструкции switch такой:switch{выражение) {case константа1:последовательность инструкцийbreak;case константа2:106Часть I.
Язык C#последовательность инструкцийbreak;case константа3:последовательность инструкцийbreak;default:последовательность инструкцийbreak;}Элемент выражение инструкции switch должен иметь целочисленный тип(например, char, byte, short или int) или тип string (о котором речь пойдет ниже вэтой книге). Выражения, имеющие тип с плавающей точкой, не разрешены. Очень часто вкачестве управляющего switch-выражения используется просто переменная; caseконстанты должны быть литералами, тип которых совместим с типом заданноговыражения. При этом никакие две case-константы в одной switch-инструкции не могутиметь идентичных значений.Последовательность инструкций default-ветви выполняется в том случае, если ниодна из заданных case-констант не совпадет с результатом вычисления switchвыражения.
Ветвь default необязательна. Если она отсутствует, то при несовпадениирезультата выражения ни с одной из case-констант никакое действие выполнено не будет.Если такое совпадение все-таки обнаружится, будут выполнены инструкции,соответствующие данной case-ветви до тех пор, пока не встретится инструкция break.Использование switch-инструкции демонстрируется в следующей программе.// Демонстрация использования инструкции switch.using System;class SwitchDemo {public static void Main() {int i;for(i=0; i<10; i++)switch(i) {case 0:Console.WriteLine("ibreak;case 1:Console.WriteLine("ibreak;case 2:Console.WriteLine("ibreak;case 3:Console.WriteLine("ibreak;case 4:Console.WriteLine("ibreak;default:Console.WriteLine("ibreak;Глава 5. Инструкции управленияравно нулю.");равно единице.");равно двум.");равно трем.");равно четырем.");равно или больше пяти.");107}}}Результаты выполнения этой программы:равно нулю.равно единице.равно двум.равно трем.равно четырем.равно или больше пяти.равно или больше пяти.равно или больше пяти.равно или больше пяти.равно или больше пяти.Как видите, на каждой итерации цикла выполняются инструкции, соответствующиеcase-константе, которая совпадает с текущим значением переменной x.
При этом всеостальные инструкции опускаются. Если i равно или больше пяти, выполняется defaultинструкция.В предыдущем примере switch-инструкция управлялась переменной типа int. Но,как вы уже знаете, для управления в switch-инструкции можно использовать переменнуюлюбого целочисленного типа, в том числе и типа char. Перед вами пример использованияв case-ветвях char-выражения и char-констант.// Использование типа char для управления// switch-инструкцией.iiiiiiiiiiusing System;class SwitchDemo2 {public static void Main() {char ch;for(ch='A'; ch<= 'E'; ch++)switch(ch) {case 'A':Console. WriteLine("ch содержит А");break;case 'B':Console.WriteLine("ch содержит В");break;case 'C':Console.WriteLine("ch содержит С");break;case 'D':Console.WriteLine("ch содержит D");break;case 'E':Console.WriteLine("ch содержит Е");break;}}}Результаты выполнения этой программы выглядят так:ch содержит Ach содержит B108Часть I.
Язык C#ch содержит Cch содержит Dch содержит EОбратите внимание на то, что в этом примере программы default-инструкцияотсутствует. Не забывайте, что она необязательна. Если в ней нет необходимости, ее можноопустить.В C# считается ошибкой, если последовательность инструкций, относящаяся к однойcase-ветви, переходит в последовательность инструкций, связанную со следующей. Здесьдолжно действовать правило запрета на передачу управления вниз, на “провал”, как говорятпрограммисты. Поэтому case-последовательности чаще всего оканчиваются инструкциейbreak. (“Провала” можно избежать и другими способами, например с помощьюинструкции goto, которая будет рассмотрена ниже в этой главе, но break — это самоераспространенное средство от “провалов”.) Инструкция break, завершающаяпоследовательность case-инструкций, приводит к выходу из всей конструкции switch ипередаче управления к следующей инструкции, находящейся вне конструкции switch.Последовательность инструкций default-ветви также не должна “проваливаться” иобычно завершается инструкцией break.Правило запрета на “провальную” передачу управления вниз — одно из отличийязыка C# от С, C++ и Java.
В этих трех упомянутых языках case-инструкции имеют право“плавно” переходить в инструкции, соответствующие следующей case-ветви, т.е.“проваливаться” вниз. Разработчики языка C# обосновали запрет на “провал” двумяследующими причинами. Во-первых, это позволяет компилятору в целях оптимизациисвободно менять порядок следования case-ветвей, что было бы невозможно, если бы однаcase-последовательность могла беспрепятственно перетекать в следующую. Во-вторых,требование явного завершения case-последовательности специальной инструкциейисключит возможность случайного “провала”, организованного программистом понедосмотру.Несмотря на запрет “провальной” передачи управления от одной caseпоследовательности к следующей, можно, как показано в следующем примере,организовать программный код так, чтобы две или больше инструкций case ссылались наодну и ту же кодовую последовательность.// "Пустые" case-инструкции могут "проваливаться".using System;class EmptyCasesCanFall {public static void Main() {int i;}}for(i=1; i < 5; i++)switch(i) {case 1:case 2:case 3:Console.WriteLine("i равно 1, 2 или 3");break;case 4:Console.WriteLine("i равно 4");break;}Глава 5.
Инструкции управления109Результаты работы этой программы вполне ожидаемы:равно 1, 2 или 3равно 1, 2 или 3равно 1, 2 или 3равно 4В этом примере, если переменная i содержит значение 1, 2 или 3, то выполняетсяпервая инструкция вызова метода WriteLine(), а если значение i равно 4, то — вторая.Показанное здесь пакетирование case-ветвей не нарушает правило запрета “провалов”,поскольку все эти case-инструкции используют одну и ту же кодовую последовательность.Такое case-пакетирование — распространенный способ совместного использованиякода несколькими case-ветвями, позволяющий устранить ненужное дублированиекодовых последовательностей.iiiiВложенные инструкции switchИнструкция switch может быть использована как часть case-последовательностивнешней инструкции switch. В этом случае она называется вложенной инструкциейswitch.
Необходимо отметить, что case-константы внутренних и внешних инструкцийswitch могут иметь одинаковые значения, при этом никаких конфликтов не возникнет.Например, следующий фрагмент кода вполне допустим:switch(ch1) {case 'A':Console.WriteLine("Эта буква А - часть внешней инструкции switch.");switch(ch2) {case 'A':Console.WriteLine("Эта буква А - часть внутренней инструкции switch.");break;case 'В': // ...} // Конец внутренней инструкции switch.break;case 'В': // ...Цикл forНачиная с главы 2, мы уже использовали простую форму цикла for.
В этой главе мырассмотрим этот цикл более детально, и вы узнаете, насколько мощным и гибким средствомпрограммирования он является. Начнем с традиционных форм его использования. Итак,общий формат записи цикла for для повторного выполнения одной инструкции имеетследующий вид:for(инициализация; условие; итерация) инструкция;Если цикл for предназначен для повторного выполнения программного блока, то егообщий формат выглядит так:for(инициализация; условие; итерация) {последовательность инструкций}Элемент инициализация обычно представляет собой инструкцию присваивания,которая устанавливает управляющую переменную цикла равной начальному значению.110Часть I. Язык C#Эта переменная действует в качестве счетчика, который управляет работой цикла.Элемент условие представляет собой выражение типа bool, в котором тестируетсязначение управляющей переменной цикла. Результат этого тестирования определяет,выполнится цикл for еще раз или нет.
Элемент итерация — это выражение, котороеопределяет, как изменяется значение управляющей переменной цикла после каждойитерации. Обратите внимание на то, что все эти элементы цикла for должны отделятьсяточкой с запятой. Цикл for будет выполняться до тех пор, пока вычисление элементаусловие дает истинный результат. Как только условие станет ложным, выполнениепрограммы продолжится с инструкции, следующей за циклом for.Управляющая переменная цикла for может изменяться как с положительным, так и сотрицательным приращением, причем величина этого приращения также может бытьлюбой. Например, следующая программа выводит числа в диапазоне от 100 до -100 сдекрементом, равным 5.// Цикл for с отрицательным приращением// управляющей переменной.using System;class DecrFor {public static void Main() {int x;for(x = 100; x > -100; x -= 5)Console.WriteLine(x);}}Важно понимать, что условное выражение всегда тестируется в начале выполненияцикла for.