
Глава 6. Операторы
6.1. Общие сведения об операторах
Операторы определяют действия и порядок выполнения действий в программе. К действиям в C# отнесли объявления (декларации), их частный случай - объявления переменных.
В стандарте языка приведена следующая классификация операторов:
помеченный (labeled-statement);
декларирующий (declaration-statement);
встроенный (embedded-statement).
Стандарт относит к встроенным следующие операторы:
блок (block);
пустой оператор (empty - statement);
оператор-выражение (expression - statement);
оператор выбора (selection - statement);
оператор цикла (iteration - statement);
оператор перехода (jump - statement);
оператор контроля за исключением (try - statement);
контроль за переполнением (checked - statement);
отмена контроля за переполнением (unchecked - statement);
оператор пространства имён (using - statement);
оператор блокировки потока (lock - statement);
итерации по коллекции (yield - statement).
В этой главе мы рассмотрим те операторы, для понимания которых не требуется изучения механизмов, отличающих язык C# от его предшественников.
Каждый оператор языка C# заканчивается разделителем "точка с запятой". Любое выражение, после которого поставлен символ "точка с запятой", воспринимается компилятором как отдельный оператор. (Исключение составляют выражения, входящие в заголовок цикла for.)
Часто оператор-выражение служит для вызова функции, не возвращающей в точку вызова никакого значения. Еще чаще оператор-выражение - это не вызов функции, а выражение с операцией присваивания. Обратите внимание, что в языке C# отсутствует отдельный оператор присваивания. Оператор присваивания всего-навсего является частным случаем оператора-выражения (с операцией присваивания).
Специальным случаем оператора служит пустой оператор. Он представляется символом "точка с запятой", перед которым нет никакого выражения или незавершенного разделителем точка с запятой оператора. Пустой оператор не предусматривает выполнения никаких действий. Он используется там, где синтаксис языка разрешает присутствия оператора, а по смыслу программы никакие действия не должны выполняться. Пустой оператор иногда используется в качестве тела цикла, когда все циклически выполняемые действия определены в заголовке цикла.
6.2. Метки и оператор безусловного перехода
Перед каждым оператором может быть помещена метка, отделяемая от оператора двоеточием. В качестве метки используется произвольно выбранный программистом уникальный идентификатор. Пример помеченного оператора:
ABC: х = 4 + х * 3;
Как уже сказано, объявления, после которых помещен символ "точка с запятой", считаются операторами. Поэтому перед ними также могут помещаться метки:
metka: int z = 0, d = 4; // Метка перед объявлением переменных
С помощью пустого оператора (перед которым имеет право стоять метка) метки можно размещать во всех точках программы, где синтаксис разрешает использовать операторы.
Говоря о помеченных операторах и метках, уместно ввести оператор безусловного перехода:
goto метка;
С помощью этого оператора обеспечивается безусловный переход к тому месту в программе, где размещена метка, использованная после служебного слова goto. Например, оператор
goto ABC;
передаст управление приведённому выше оператору АВС:х=4+х*3;
В современном программировании оператор безусловного перехода используется достаточно редко, но в некоторых случаях он может оказаться весьма полезным.
Переход к метке возможен в общем случае не из всех точек программы. Важно, где размещена метка и где находится оператор перехода. В связи с существующими ограничениями на выполнение переходов нужно познакомиться с понятием блока.
Блок - заключенная в фигурные скобки последовательность операторов. Среди этих операторов могут присутствовать операторы объявлений. В блоке локализованы все объявленные в нем объекты, в том числе и метки. Синтаксически блок является отдельным оператором. Однако блок не требуется завершать точкой с запятой. Для блока ограничителем служит закрывающая фигурная скобка. Внутри блока каждый оператор должен оканчиваться точкой с запятой. Примеры блоков:
{ int a; char b = '0'; a = (int)b; }
{ func(z + 1.0, 22); e = 4 * x - 1; }
Говоря о блоках, нужно понимать правила определения сферы действия имен и ограничения видимости объектов. Разрешено вложение блоков, причем на глубину вложения синтаксис не накладывает ограничений. О входе в блок стоит сказать уже сейчас - запрещено извне переходить к внутренним операторам блока.
Тем самым метки внутри блока недостижимы для оператора перехода, размещённого вне блока. В то же время для оператора перехода, размещённого внутри блока, разрешён переход к метке вне блока.