Г. Шилдт - Полный справочник по C# (1160789), страница 22
Текст из файла (страница 22)
Если такое совпадение все-таки обнаружится, будут выполнены инструкции,соответствующие данной case-ветви до тех пор, пока не встретится инструкцияbreak.Использование switch-инструкции демонстрируется в следующей программе.// Демонстрация использования инструкции s w i t c h .using System;class SwitchDemo {public static void Main() {int i;for(i=0; iswitch (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.
Инструкции управления^равно нулю.");равно единице.");равно двум.");/равно трем.");равно четырем.");равно или больше пяти.");107iiiiiiiiiiРезультаты выполнения этой программы:равно нулю.равно единице.равно двум.равно трем.равно четырем.равно или больше пяти.равно или больше пяти.равно или больше пяти.равно или больше пяти.равно или больше пяти.Как видите, на каждой итерации цикла выполняются инструкции, соответствующие case-константе, которая совпадает с текущим значением переменной i.
Приэтом все остальные инструкции опускаются. Если i равно или больше пяти, выполняется default-инструкция.В предыдущем примере switch-инструкция управлялась переменной типа i n t .Но, как вы уже знаете, для управления в switch-инструкции можно использовать переменную любого целочисленного типа, в том числе и типа char. Перед вами примериспользования в case-ветвях char-выражения и char-констант.// Использование типа char для управления// switch-инструкцией.u s i n g System;c l a s s SwitchDemo2 {p u b l i c s t a t i c void Main() {char ch;f o r ( c h = ' A f ; ch<= ' E ' ; ch++)switch(ch) {case ' A ' :Console.WriteLine("chbreak;case f B f :Console.WriteLine("chbreak;case f C f :Console.WriteLine("chbreak;case r D r :Console.WriteLine("chbreak;case f E ' :Console.WriteLine("chbreak;содержит А " ) ;содержит В " ) ;содержит С " ) ;содержит D " ) ;содержит Е " ) ;Результаты выполнения этой программы выглядят так:ch содержит Аch содержит В108Часть I.
Язык С#§ ch содержит СI ch содержит DI ch содержит ЕОбратите внимание на то, что в этом примере программы default-инструкция отсутствует. Не забывайте, что она необязательна. Если в ней нет необходимости, ееможно опустить.В С# считается ошибкой, если последовательность инструкций, относящаяся к одной case-ветви, переходит в последовательность инструкций, связанную со следующей. Здесь должно действовать правило запрета на передачу управления вниз, на"провал", как говорят программисты.
Поэтому case-последовательности чаще всегооканчиваются инструкцией break. ("Провала" можно избежать и другими способами,например с помощью инструкции goto, которая будет рассмотрена ниже в этой главе,но break — это самое распространенное средство от "провалов".) Инструкция break,завершающая последовательность case-инструкций, приводит к выходу из всей конструкции switch и передаче управления к следующей инструкции, находящейся внеконструкции switch.
Последовательность инструкций default-ветви также не должна "проваливаться" и обычно завершается инструкцией break.Правило запрета на "провальную" передачу управления вниз — одно из отличийязыка С# от С, C++ и Java. В этих трех упомянутых языках case-инструкции имеютправо "плавно" переходить в инструкции, соответствующие следующей case-ветви,т.е. "проваливаться" вниз. Разработчики языка С# обосновали запрет на "провал"двумя следующими причинами.
Во-первых, это позволяет компилятору в целях оптимизации свободно менять порядок следования case-ветвей, что было бы невозможно,если бы одна case-последовательность могла беспрепятственно перетекать в следующую. Во-вторых, требование явного завершения case-последовательности специальной инструкцией исключит возможность случайного "провала", организованногопрограммистом по недосмотру.Несмотря на запрет "провальной" передачи управления от одной caseпоследовательности к следующей, можно, как показано в следующем примере, организовать программный код так, чтобы две или больше инструкций case ссылались наодну и ту же кодовую последовательность.// "Пустые" case-инструкции могут "проваливаться".using System;class EmptyCasesCanFall {public static void Main() {int i ;for(i=l; i < 5;switch(i) {case 1:case 2:case 3: Console.WriteLine("i равно 1, 2 или З " ) ;break;c a s e 4: C o n s o l e .
W r i t e L i n e ( " 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(chl) {case f A f :Console.WriteLine("Эта буква А - часть внешней инструкции switch.");switch(ch2) {case 'A 1 :Console.WriteLine("Эта буква А - часть внутренней инструкции switch.");break;case 'В': // ...} // Конец внутренней инструкции switch,break;case 'B f : // ...Цикл f o rНачиная с главы 2, мы уже использовали простую форму цикла for.
В этой главемы рассмотрим этот цикл более детально, и вы узнаете, насколько мощным и гибкимсредством программирования он является. Начнем с традиционных форм его использования. Итак, общий формат записи цикла for для повторного выполнения однойинструкции имеет следующий вид:for{инициализация; условие; итерация) инструкция;Если цикл for предназначен для повторного выполнения программного блока, тоего общий формат выглядит так:for{инициализация; условие; итерация){последовательность инструкций}Элемент инициализация обычно представляет собой инструкцию присваивания,которая устанавливает управляющую переменную цикла равной начальному значению.110-Часть I. Язык С#Эта переменная действует в качестве счетчика, который управляет работой цикла.Элемент условие представляет собой выражение типа bool, в котором тестируетсязначение управляющей переменной цикла.
Результат этого тестирования определяет,выполнится цикл f o r еще раз или нет. Элемент итерация —- это выражение, котороеопределяет, как изменяется значение управляющей переменной цикла после каждойитерации. Обратите внимание на то, что все эти элементы цикла f o r должны отделяться точкой с запятой. Цикл f o r будет выполняться до тех пор, пока вычислениеэлемента условие дает истинный результат. Как только условие станет ложным, выполнение программы продолжится с инструкции, следующей за циклом for.Управляющая переменная цикла for может изменяться как с положительным, таки с отрицательным приращением, причем величина этого приращения также можетбыть любой.
Например, следующая программа выводит числа в диапазоне от 100 до 100 с декрементом, равным 5.// Цикл for с отрицательным приращением// управляющей переменной.using System;class DecrFor {public s t a t i c void Main() {int x;for(x = 100; x > -100; x -= 5)Console.WriteLine(x);|Важно понимать, что условное выражение всегда тестируется в начале выполненияцикла for. Это значит, что если первая же проверка условия даст значение ЛОЖЬ,код тела цикла не выполнится ни разу. Вот пример:for(count=10; count < 5; count++)х += count; // Эта инструкция не будет выполнена вовсе.Этот цикл никогда не выполнится, поскольку уже при входе в него значение егоуправляющей переменной count больше пяти.
Это делает условное выражение(count < 5) ложным с самого начала. Поэтому даже одна итерация этого цикла не будет выполнена.Цикл for особенно полезен в тех случаях, когда известно количество его повторений. Например, следующая программа использует два цикла f o r для отыскания простых чисел в диапазоне от 2 до 20. Если число не простое, программа отобразит егосамый большой множитель./*Программа определения простых чисел.Если число не простое, программа отображаетего самый большой множитель.*/using System;class FindPrimes {public static void Main() {int num;int i;int factor;bool isprime;for(num = 2; num < 20; num++) {Глава 5.
Инструкции управления111isprime = true;factor = 0;// Узнаем, делится ли num на i без остатка.for(i=2; i <= num/2; i++) {if((num % i) == 0) {// Если num делится на i без остатка,// значит num — число не простое,isprime = falserfactor = i;if(isprime)Console.WriteLine(num + " -- простое число.");elseConsole.WriteLine("Максимальный множитель числаnum + " равен " + factor);Результаты выполнения этой программы имеют такой вид:2 -- простое число.3 — простое число.Максимальный множитель числа 4 равен 25 -- простое число.Максимальный множитель числа б равен 37 — простое число.Максимальный множитель числа 8 равен 4Максимальный множитель числа 9 равен 3Максимальный множитель числа 10 равен 511 — простое число.Максимальный множитель числа 12 равен б13 — простое число.Максимальный множитель числа 14 равен 7Максимальный множитель числа 15 равен 5Максимальный множитель числа 16 равен 817 -- простое число.Максимальный множитель числа 18 равен 919 — простое число.Вариации на тему цикла forЦикл for — одна из наиболее гибких инструкций в С#, поскольку она позволяетполучить широкий диапазон вариаций.Использование нескольких управляющих переменных циклаДля управления циклом for можно использовать две или больше переменных.
Вэтом случае инструкции инициализации и итерации для каждой из этих переменных^отделяются запятыми. Вот пример:// Использование запятых в цикле for.using System;class Comma {112Часть I. Язык С#public static void Main() {int i, j ;for(i=0, j=10; i < j; i++, j — )Console.WriteLine("i и j: " + i + " " + j ) ;Вот как выглядят результаты выполнения этой программы:и 3-: 0 101 9и jи j: 2 8и j: 3 7и i: 4 6Здесь запятыми отделяются две инструкции инициализации и два итерационныхвыражения. При входе в цикл инициализируются обе переменные — i и j . Послевыполнения каждой итерации цикла переменная i инкрементируется, а переменная jдекрементируется.
Использование нескольких управляющих переменных в циклеиногда позволяет упростить алгоритмы. В разделах инициализации и итерации циклаfor можно использовать любое количество инструкций, но обычно их число не превышает двух.Приведем пример практического использования двух управляющих переменных вцикле for. Рассмотрим программу, которая находит наибольший и наименьшиймножители числа (в данном случае числа 100). Обратите особое внимание на условие^завершения цикла: оно включает обе управляющих переменных./*Использование запятых в цикле for для определениянаибольшего и наименьшего множителей числа.*/1iiiiusing System;class Comma {public static void Main() {int i, j;int smallest, largest;int num;num = 100;smallest = largest = 1;for(i=2, j=num/2; (i <= num/2) & (j >= 2 ) ; i++, j — ) {if((smallest == 1) & ((num % i) == 0))smallest = i;if((largest == 1) & ((num % j) == 0))largest = j;Console.WriteLine("Наибольший множитель: " + l a r g e s t ) ;Console.WriteLine("Наименьший множитель: " + s m a l l e s t ) ;Результаты выполнения этой программы выглядят так:Глава 5.