netlib.narod.ru | < Назад | Оглавление | Далее > |
В С# поддерживаются многие применяемые в С условные инструкции, инструкции цикла и управления выполнением программы. В этом разделе я рассмотрю инструкции, содержащие ключевые слова if, else, do, while, switch, case, default, for, foreach, in, break, continue и goto.
Конструкции if и else выглядят точно так же, как в С:
if (a == 5) { ... } else if (a < 5) { ... } else { ... }
Однако в С# выражения в скобках должны иметь тип bool. Такое ограничение позволяет избежать общеизвестного подводного камня языка С — ошибочного использования в проверяемом выражении оператора присваивания вместо оператора сравнения:
if (a = 5)
Такой оператор вызовет в С# ошибку компиляции, и скажите за это спасибо С#.
Но, конечно, ни один компилятор не обеспечивает полной защиты от рассеянности программиста. В одной из своих первых программ на С# я определил переменную trigger типа bool, но вместо инструкции
if (trigger)
я, чтобы сделать программу чуть понятнее, хотел ввести
if (trigger == true)
Но, к сожалению, я ввел:
if (trigger = true)
Это совершенно корректная, с точки зрения С#, инструкция, но, очевидно, она делает не то, что я хотел.
Кроме того, С# поддерживает инструкции do и while. Можно проверять условие перед выполнением блока:
while (a < 5) { ... }
или после:
do { ... } while (a < 5);
Здесь выражение также должно иметь тип bool. Во втором случае блок выполнится хотя бы раз независимо от значения а.
В конструкции switch/case языка С# есть ограничение, которого нет в С. В С допускается инструкция:
switch (a) { case 3: b = 7; // В С# запрещено прохождение через case. case 4: с = 3; break; default: b = 2; с = 4; break; }
Если а равно 3, выполнится первый оператор, затем программа «перешагнет» через case, в котором а равно 4. Может, вы именно так и задумали, но возможно, что вы просто забыли поставить инструкцию break. Чтобы избежать ситуаций такого рода, компилятор С# сообщает об ошибке. С# позволяет проходить через case, только если case не содержит инструкций. Вот какая конструкция допустима в С#:
switch (a) { case 3: case 4: b = 7; с = 3; break; default: b = 2; с = 4; break; }
Если требуется нечто более сложное, можно использовать инструкцию goto, описанную в этом разделе далее.
Одна из приятных возможностей C#: в инструкции switch можно использовать строковую переменную, сравниваемую в инструкциях case со строковыми константами:
switch (strCity) { case "Boston": ... break; case "New York": ... break; case "San Francisco": ... break; default: ... break; }
Конечно, такой фрагмент кода вызовет ужас у заботящихся о производительности программистов на С или C++. Все эти сравнения строк просто не могут быть особо эффективными. На самом деле, благодаря технологии интернирования строк (string interning), заключающейся в поддержке таблицы всех используемых в программе уникальных строк, он работает гораздо быстрее, чем может показаться.
Цикл for выглядит в С# точно так же, как в С и C++:
for (i = 0; i < 100; i += 3) { ... }
Как и в C++, в С# широко используется определение переменной цикла прямо в инструкции for:
for (float f = 0; f < 10.05f; f += 0.1f) { ... }
Удобным дополнением к этому типу цикла является инструкция foreach, позаимствованная С# из Visual Basic. Предположим, arr — массив значений типа float. Если требуется показать все его элементы в одной строке, разделив их пробелами обычно делают так:
for {int i = 0; i < arr.Length; i++) Console.Write("{0} ", arr[i]);
Инструкция foreach, в которой используется ключевое слово in, упрощает эту операцию:
foreach (float f in arr) Console.Write("{0} ", f);
Для параметра цикла foreach (в данном случае переменной f) надо в инструкции foreach указать тип данных; в следующем за foreach блоке инструкций параметр цикла доступен только для чтения. Следовательно, foreach не годится для инициализации элементов массива:
int[] arr = new int[100]; foreach (int i in arr) // Так нельзя! i = 55;
Интересно, что инструкция foreach может работать не только с массивами, но и с любыми классами, реализующими интерфейс IEnumerable, определенный в пространстве имен System.Collections. Более ста классов .NET Framework реализуют интерфейс IEnumerable. (Здесь я лишь коснусь интерфейсов, а в главе 8 рассмотрю их подробно.)
Инструкция break обычно используется в конструкциях switch/case, а также для выхода из циклов while, do, for и foreach. Инструкция continue служит для перехода к концу блока, выполняемого в цикле while, do, for или foreach и выполнении следующей итерации цикла (если эта итерация должна выполняться согласно условию цикла).
И, наконец, инструкция goto:
goto MyLabel; ... MyLabel:
полезна для выхода из блоков с большой вложенностью и написания запутанного кода. Кроме того, в С# поддерживается инструкция goto в конструкции switch/case для перехода к другой ветви:
switch (a) { case 1: b = 2; goto case 3; case 2: с = 7; goto default; case 3: с = 5; break; default: b = 2; break; }
Если вместо break используется goto, то инструкция break в конце ветви не нужна. Эта возможность компенсирует запрет проходить через case.
netlib.narod.ru | < Назад | Оглавление | Далее > |