Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Podbelsky_V_V_C_Bazovy_kurs.pdf
Скачиваний:
69
Добавлен:
02.06.2015
Размер:
1.73 Mб
Скачать

Операторы

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#

Операторы

77

 

 

отсутствует отдельный оператор присваивания. Оператор присваивания всего-навсего является частным случаем операторавыражения (с операцией присваивания).

Специальным случаем оператора служит пустой оператор. Он представляется символом «точка с запятой», перед которым нет никакого выражения или незавершенного разделителем точка с запятой оператора. Пустой оператор не предусматривает выполнения никаких действий. Он используется там, где синтаксис языка разрешает присутствие оператора, а по смыслу программы никакие действия не должны выполняться. Пустой оператор иногда используется в качестве тела цикла, когда все циклически выполняемые действия определены в заголовке цикла.

6.2. Метки и оператор безусловного перехода

Перед каждым оператором может быть помещена метка, отделяемая от оператора двоеточием. В качестве метки используется произвольно выбранный программистом уникальный идентификатор. Пример помеченного оператора:

ABC: x = 4 + x * 3;

Как уже сказано, объявления, после которых помещен символ «точка с запятой», считаются операторами. Поэтому перед ними также могут помещаться метки:

metka: int z = 0, d = 4; // Метка перед объявлением

С помощью пустого оператора (перед которым имеет право стоять метка) метки можно размещать во всех точках программы, где синтаксис разрешает использовать операторы.

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

goto метка;

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

goto АВС;

78 Г л а в а 6

передаст управление приведенному выше оператору АВС:х=4+х*3;

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

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

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

{int a; char b = '0'; a = (int)b; }

{func(z + 1.0, 22); e = 4 * x - 1; }

Говоря о блоках, нужно понимать правила определения области действия имен и ограничения видимости объектов. Разрешено вложение блоков, причем на глубину вложения синтаксис не накладывает ограничений. Запрещено извне переходить к внутренним опеаторам блока.

Тем самым метки внутри блока недостижимы для оператора перехода, размещенного вне блока. В то же время для оператора перехода, размещенного внутри блока, разрешен переход к метке вне блока.

6.3. Условный оператор (ветвлений)

К операторам выбора, называемым операторами ветвлений, относят: условный оператор (if...else) и переключатель (switch). Каждый из них служит для выбора «пути» выполнения программы. (О переключателе см. разд. 6.6).

Операторы

79

 

 

Синтаксис условного оператора:

if (логическое выражение) оператор_1 else оператор_2

Логическое выражение иногда называют проверяемым условием. Если логическое выражение равно true, выполняется оператор_1. В противном случае, когда выражение равно false, выполняется оператор_2. В качестве операторов, входящих в условный оператор, нельзя использовать объявления. Однако, здесь могут быть блоки и в них допустимы объявления.

Примеры:

if (x > 0) x; double x=4; f(x * 2); } else { int i = 2; double x = i*i; f(x); }

При использовании блоков нельзя забывать о локализации определяемых в блоке объектов. Например, ошибочна будет такая конструкция:

if (j > 0) { int i; i = 2 * j; } else i = j;

Здесь предполагается, что переменная j определена и имеет конкретное значение. Ошибка в том, что переменная i локализована в блоке и не существует вне блока.

Допустима сокращенная форма условного оператора, в которой отсутствует else и оператор_2. В этом случае при ложности проверяемого условия никакие действия не выполняются, например:

if (a < 0) a = -a;

Оператор_1 и оператор_2 могут быть условными, что позволяет организовать цепочку проверок условий любой глубины вложенности. В этих цепочках каждый из условных операторов (после проверяемого условия и после else) может быть как полным условным, так и иметь сокращенную форму записи. При этом могут возникать ошибки неоднозначного сопоставления if и else. Синтаксис языка предполагает, что при вложениях условных операторов каждое else соответствует ближайшему к нему предшествующему if.

В качестве примера вложения условных операторов приведём фрагмент программы, в котором переменной result необходимо

80

Г л а в а 6

 

 

присвоить максимальное из трёх значений переменных x, y, z. (Объявление и инициализация переменных опущены).

if (x<y)

if (y<z) result = z; else result = y;

else

if (x<z) result = z; else result = x;

В тексте соответствие if и else показано с помощью отступов.

6.4. Операторы цикла

Операторы цикла задают многократное исполнение операторов тела цикла. В языке C# определены четыре разных оператора цикла.

Цикл с предусловием:

while (выражение-условие) тело_цикла

Цикл с постусловием:

do

тело_цикла

while (выражение-условие);

Параметрический цикл (цикл общего вида):

for (инициализатор_цикла;

выражение-условие; завершающее_ выражение) тело_цикла

Цикл перебора элементов массива или коллекции:

foreach (тип идентификатор in выражение) тело_цикла

while, do, for, foreach, in – служебные слова, применяемые только для создания циклов. Оператор foreach будет рассмотрен при изучении массивов (глава 7). А теперь рассмотрим остальные циклы и их элементы.

Тело_цикла не может быть объявлением. Это либо отдельный (в том числе пустой) оператор, который всегда завершается

Операторы

81

 

 

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

●●ложное (false) значение проверяемого выражения-условия; ●●выполнение в теле цикла оператора передачи управления

(break, goto, return) за пределы цикла.

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

Оператор while (оператор «повторять, пока истинно условие») называется оператором цикла с предусловием. При входе в цикл вычисляется выражение-условие. Если его значение истинно, то выполняется тело_цикла. Затем вычисление выражения-условия и выполнение операторов тела_цикла повторяются последовательно, пока значение выражения-условия остается истинным и нет явной передачи управления за пределы тела цикла.

Оператором while удобно пользоваться для просмотра последовательностей, если в конце каждой из них находится заранее известный признак.

В качестве проверяемого выражения-условия в циклах часто используются отношения. Например, следующая последовательность операторов вычисляет сумму квадратов первых К натуральных чисел (членов натурального ряда):

int i = 0;

// Cчетчик

int s = 0;

// Будущая сумма

while (i ++< K) //Цикл вычисления суммы s += i * i;

Только при изменении операндов выражения-условия можно избежать зацикливания. Поэтому, используя оператор цикла с предусловием, необходимо следить за тем, чтобы операторы тела_цикла воздействовали на выражение-условие, либо оно еще каким-то образом должно изменяться во время вычислений. Например, могут изменяться операнды выражения-усло- вия. Часто для этих целей используют унарные операции ++ и --.) Только при изменении выражения-условия можно избежать зацикливания. В качестве примера использования оператора

82

Г л а в а 6

 

 

while рассмотрим программу, которая предлагает пользователю ввести текстовую информацию (непустую строку). Если пользователь нажимает ENTER, не введя никаких данных, то предложение «Ввести данные» повторяется.

// 06_01.cs цикл с предусловием using System;

class Program

{

static void Main()

{

string name = ""; while (name == "")

{

Console.Write("Введите имя: "); name = Console.ReadLine();

}

}

}

Результат выполнения программы:

Введите имя:<ENTER> Введите имя:<ENTER> Введите имя: ReENTER>

В данной программе предлагается ввести имя, и введенная строка, представляемая переменной name, сравнивается с пустой строкой. Проверка корректности введенных данных в реальных программах может быть гораздо более сложной. Но общая схема применения оператора цикла будет пригодна и в этих более сложных случаях. Цикл не прекращается, пока не будут введены правильные (по смыслу задачи) данные.

Оператор do (оператор «повторять») называется оператором цикла с постусловием. Он имеет следующий вид:

do

тело_цикла

while (выражение-условие);

При входе в цикл do постусловием тело_цикла хотя бы один раз обязательно выполняется. Затем вычисляется выражение-ус- ловие и, если его значение равно true, вновь выполняется тело_

Операторы

83

 

 

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

К выражению-условию в цикле do требования те же, что и для цикла while – оно должно изменяться при итерациях либо за счет операторов тела цикла, либо при вычислениях значения выражения-условия.

В предыдущей программе цикл с предусловием можно заменить таким циклом с постусловием:

do

{ Console.Write ("Введите имя:"); name = Console.ReadLine();}

while (name=="");

Оператор параметрического цикла for или цикл общего вида имеет формат:

for (инициализатор_цикла; выражение_условие; завершающее_выражение)

тело_цикла

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

в цикле инициализатора_цикла, выражения-условия и завершающего_выражения разделяющие их символы «точка с запятой» всегда присутствуют, т. е. в заголовке цикла for всегда имеются два символа ‘;’.

Выражение-условие такое же, как и в циклах while и do. Если оно равно false, то выполнение цикла прекращается. В случае

84

Г л а в а 6

 

 

отсутствия выражения-условия следующий за ним разделитель «точка с запятой» сохраняется, и предполагается, что значение

выражения_условия всегда истинно.

Завершающее_выражение (в цикле for) – достаточно часто представляет собой последовательность скалярных выражений, разделенных запятыми. Эти выражения вычисляются на каждой итерации после выполнения операторов тела цикла, т.е. перед следующей проверкой выражения-ус- ловия.

Тело_цикла, как уже сказано, может быть блоком, отдельным оператором и пустым оператором. Определенные в инициализаторе цикла объекты существуют только в заголовке и в теле цикла. Если результаты выполнения цикла нужны после его окончания, то их нужно сохранять во внешних относительно цикла объектах.

В следующей программе использованы три формы оператора for. В каждом из циклов решается одна и та же задача суммирования квадратов первых k членов натурального ряда:

// 06_02.cs параметрический цикл (цикл общего

вида).

using System; class Program

{

static void Main()

{

int k = 3, s = 0, i = 1; for (; i <= k; i++)

s += i * i; Console.WriteLine("Сумма = " + s);

s = 0; k = 4; // Начальные значения s, k. for (int j = 0; j < k; )

s += ++j * j; Console.WriteLine("Сумма = " + s);

for (i = 0, s = 0, k = 5; i <= k; s += i * i, i++); Console.WriteLine("Сумма = " + s);

}

}

Операторы

85

 

 

Результат выполнения программы:

Сумма = 14 Сумма = 30 Сумма = 55

Все переменные в первом цикле внешние, отсутствует инициализатор цикла, в завершающем выражении заголовка изменяется параметр цикла i. После выполнения цикла результат сохраняется в переменной s и выводится. Перед вторым циклом s обнуляется, а переменной k присваивается значение 4. Инициализатор второго цикла определяет локализованную в цикле переменную j. В заголовке отсутствует завершающее выражение, а параметр цикла j изменяется в его теле (вне заголовка). Инициализатор третьего цикла – выражение, операнды которого разделены запятыми. В этом выражении подготавливается выполнение цикла – обнуляются значения i и s, и присваивается значение 5 переменной k. Остальное должно быть понятно.

Итак, еще раз проследим последовательность выполнения цикла for. Определяются и инициируются объекты, т. е. вычисляется выражение инициализатора_цикла. Вычисляется значение выражения-условия. Если оно равно true, выполняются операторы тела_цикла. Затем вычисляется завершающее выражение, вновь вычисляется выражение-условие, и проверяется его значение. Далее цепочка действий повторяется. Оператору for может быть поставлен в соответствие следующий блок:

{

инициализатор_цикла; while (выражение-условие) {

операторы_тела_цикла завершающее_выражение;

}

}

При выполнении цикла for выражение-условие может изменяться либо при вычислении его значений, либо под действием операторов тела цикла, либо под действием завершающего выражения. Если выражение-условие не изменяется либо отсутствует, то цикл бесконечен. Следующий оператор обеспечивает бесконечное выполнение пустого оператора:

for( ; ;); // Бесконечный цикл

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]