Интернет-журнал "Домашняя лаборатория", 2007 №9 - Журнал «Домашняя лаборатория»
Шрифт:
Интервал:
Закладка:
Оператор присваивания
Как в языке C++, так и в C# присваивание формально считается операцией. Вместе с тем запись:
X = expr;
следует считать настоящим оператором присваивания, так же, как и одновременное присваивание со списком переменных в левой части:
X1 = X2 =… = Xk = expr;
В отличие от языка C++ появление присваивания в выражениях C# хотя и допустимо, но практически не встречается. Например, запись:
if(х = expr)…
часто используемая в C++, в языке C# в большинстве случаев будет воспринята как ошибка еще на этапе компиляции.
В предыдущих лекциях семантика присваивания разбиралась достаточно подробно, поэтому сейчас я на этом останавливаться не буду.
Блок или составной оператор
С помощью фигурных скобок несколько операторов языка (возможно, перемежаемых объявлениями) можно объединить в единую синтаксическую конструкцию, называемую блоком или составным оператором:
{
оператор_1
…
оператор_N
}
В языках программирования нет общепринятой нормы для использования символа точки с запятой при записи последовательности операторов. Есть три различных подхода и их вариации. Категорические противники точек с запятой считают, что каждый оператор должен записываться на отдельной строке (для длинных операторов определяются правила переноса). В этом случае точки с запятой (или другие аналогичные разделители) не нужны. Горячие поклонники точек с запятой (к ним относятся языки C++ и С#) считают, что точкой с запятой должен оканчиваться каждый оператор. В результате в операторе if перед else появляется точка с запятой. Третьи полагают, что точка с запятой играет роль разделителя операторов, поэтому перед else ее не должно быть. В приведенной выше записи блока, следуя синтаксису С#, каждый из операторов заканчивается символом "точка с запятой". Но, заметьте, блок не заканчивается этим символом!
Синтаксически блок воспринимается как единичный оператор и может использоваться всюду в конструкциях, где синтаксис требует одного оператора. Тело цикла, ветви оператора if, как правило, представляются блоком. Приведу достаточно формальный и слегка запутанный пример, где тело процедуры представлено блоком, в котором есть встроенные блоки, задающие тело оператора цикла for и тела ветвей оператора if:
/// <summary>
/// демонстрация блоков (составных операторов)
/// </summary>
public void Block()
{
int limit = 100;
int x = 120, у = 50;
int sum1 =0, sum2=0;
for (int i = 0; i< 11; i++)
{
int step = Math.Abs(limit — x)/10;
if (x > limit)
{x — = step; у += step;}
else
{x += step; у — = step;}
sum1 += x; sum2 +=y;
}
//limit = step; //переменная step перестала существовать
//limit = i; // переменная i перестала существовать
Console.WriteLine("x= {0}, y= {1}, sum1 ={2}, sum2 = {3}",
x, у, sum1,sum2);
}
Заметьте, здесь в тело основного блока вложен блок, задающий тело цикла, в котором объявлены две локальные переменные — i и step.
В свою очередь, в тело цикла вложены блоки, связанные с ветвями then и else оператора if. Закомментированные операторы, стоящие сразу за окончанием цикла, напоминают, что соответствующие локальные переменные, определенные в блоке, перестают существовать по его завершении.
Приведенная процедура Block является методом класса Testing, который входит в проект statements, созданный для работы с примерами этой лекции. Вот описание полей и конструктора класса Testing:
/// <summary>
/// Класс Testing — тестирующий класс. Представляет набор
/// скалярных переменных и методов, тестирующих работу
/// с операторами, процедурами и функциями С#.
/// </summary>
public class Testing
{
public Testing(string name, int age)
{
this.age = age;
this.name = name;
}
//поля класса
public string name;
public int age;
private int period;
private string status;
}
Пустой оператор
Пустой оператор — это "пусто", завершаемое точкой с запятой. Иногда полезно рассматривать отсутствие операторов как существующий пустой оператор. Синтаксически допустимо ставить лишние точки с запятой, полагая, что вставляются пустые операторы. Например, синтаксически допустима следующая конструкция:
for (int j=1; j<5; j++)
{;;;};
Она может рассматриваться как задержка по времени, работа на холостом ходе.
Операторы выбора
Как в C++ и других языках программирования, в языке C# для выбора одной из нескольких возможностей используются две конструкции — if и switch. Первую из них обычно называют альтернативным выбором, вторую — разбором случаев.
Оператор if
Начнем с синтаксиса оператора if:
if(выражение_1) оператор_1
else if(выражение_2) оператор_2
…
else if(выражение_К) оператор_К
else оператор_N
Какие особенности синтаксиса следует отметить? Выражения if должны заключаться в круглые скобки и быть булевого типа. Точнее, выражения должны давать значения true или false. Напомню, арифметический тип не имеет явных или неявных преобразований к булевому типу. По правилам синтаксиса языка C++, then-ветвь оператора следует сразу за круглой скобкой без ключевого слова then, типичного для большинства языков программирования. Каждый из операторов может быть блоком — в частности, if-оператором. Поэтому возможна и такая конструкция:
if(выражение 1) if(выражение2) if(выражение 3)…
Ветви else и if, позволяющие организовать выбор из многих возможностей, могут отсутствовать. Может быть опущена и заключительная else-ветвь. В этом случае краткая форма оператора if задает альтернативный выбор — делать или не делать — выполнять или не выполнять then-оператор.
Семантика оператора if проста и понятна. Выражения if проверяются в порядке их написания. Как только получено значение true, проверка прекращается и выполняется оператор (это может быть блок), который следует за выражением, получившим значение true, с завершением этого оператора завершается и оператор if. Ветвь else, если она есть, относится к ближайшему открытому if.
Оператор switch
Частным, но важным случаем выбора из нескольких вариантов является ситуация, при которой выбор варианта определяется значениями некоторого выражения. Соответствующий оператор С#, унаследованный от C++, но с небольшими изменениями в синтаксисе, называется оператором switch. Вот его синтаксис:
switch(выражение)
{
case константное_выражение_1: [операторы_1 оператор_перехода_1]
…
case константное_выражение_К: [операторы_К оператор_перехода_К]