Состав операторов языка C#, их синтаксис и семантика унаследованы от языка С++. Как и положено, потомок частично дополнил состав, переопределил синтаксис и семантику отдельных операторов, постарался улучшить характеристики языка во благо программиста. Посмотрим, насколько это удалось языку C#.
Как в языке С++, так и в C#
X = expr;
следует считать настоящим
X1 = X2 = ... = Xk = expr;
В отличие от языка C++ появление
if(x = expr)...
часто используемая в С++, в языке C# в большинстве случаев будет воспринята как ошибка еще на этапе компиляции.
В предыдущих лекциях семантика
С помощью фигурных скобок несколько операторов языка (возможно, перемежаемых объявлениями) можно объединить в единую синтаксическую конструкцию, называемую
{
оператор_1
...
оператор_N
}
В языках программирования нет общепринятой нормы для использования символа точки с запятой при записи последовательности операторов. Есть три различных подхода и их вариации. Категорические противники точек с запятой считают, что каждый оператор должен записываться на отдельной строке (для длинных операторов определяются правила переноса). В этом случае точки с запятой (или другие аналогичные разделители) не нужны. Горячие поклонники точек с запятой (к ним относятся языки С++ и C#) считают, что точкой с запятой должен оканчиваться каждый оператор. В результате в |
Синтаксически
/// <summary>
/// демонстрация блоков (составных операторов)
/// </summary>
public void Block()
{
int limit = 100;
int x = 120, y = 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; y += step;}
else
{x += step; y -= step;}
sum1 += x; sum2 +=y;
}
//limit = step; //переменная step перестала существовать
//limit = i; // переменная i перестала существовать
Console.WriteLine("x= {0}, y= {1}, sum1 ={2}, sum2 = {3}",
x,y,sum1,sum2);
}
Заметьте, здесь в тело основного i и step.
В свою очередь, в тело цикла вложены then и else
Приведенная процедура Block является методом класса Testing, который входит в проект Statements, созданный для работы с примерами этой лекции. Вот описание полей и конструктора класса Testing:
/// <summary>
/// Класс Testing - тестирующий класс. Представляет набор
/// скалярных переменных и методов, тестирующих работу
/// с операторами, процедурами и функциями C#.
/// </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# для выбора одной из нескольких возможностей используются две конструкции -
Начнем с синтаксиса
if(выражение_1) оператор_1 else if(выражение_2) оператор_2 ... else if(выражение_K) оператор_K else оператор_N
Какие особенности синтаксиса следует отметить? Выражения true или false. Напомню, арифметический тип не имеет явных или неявных преобразований к булевому типу. По правилам синтаксиса языка С++, then -ветвь оператора следует сразу за круглой скобкой без ключевого слова then, типичного для большинства языков программирования. Каждый из операторов может быть
if(выражение1) if(выражение2) if(выражение3) ...
Ветви else и else -ветвь. В этом случае краткая форма then -оператор.
Семантика true, проверка прекращается и выполняется оператор (это может быть true. С завершением этого оператора завершается и else, если она есть, относится к ближайшему открытому
Частным, но важным случаем выбора из нескольких вариантов является ситуация, при которой выбор варианта определяется значениями некоторого выражения. Соответствующий оператор C#, унаследованный от C++, но с небольшими изменениями в синтаксисе, называется
switch(выражение)
{
case константное_выражение_1: [операторы_1 оператор_перехода_1]
...
case константное_выражение_K: [операторы_K оператор_перехода_K]
[default: операторы_N оператор_перехода_N]
}
Ветвь default может отсутствовать. Заметьте, по синтаксису допустимо, чтобы после двоеточия следовала пустая последовательность операторов, а не последовательность, заканчивающаяся
Семантика switch -выражения. Затем оно поочередно в порядке следования case сравнивается на совпадение с константными выражениями. Как только достигнуто совпадение, выполняется соответствующая последовательность операторов case -ветви. Поскольку последний оператор этой последовательности является break ), то обычно он завершает выполнение case -ветви, которая, в свою очередь, может передать управление еще куда-нибудь, получая блюдо "спагетти" вместо хорошо структурированной последовательности операторов. Семантика осложняется еще и тем, что case -ветвь может быть пустой последовательностью операторов. Тогда в случае совпадения константного выражения этой ветви со значением switch -выражения будет выполняться первая непустая последовательность очередной case -ветви. Если значение switch -выражения не совпадает ни с одним константным выражением, то выполняется последовательность операторов ветви default, если же таковой ветви нет, то
Полагаю, что |
Еще одна неудача в синтаксической конструкции case -выражения, которые могут быть только константным выражением. Уж если изменять оператор, то гораздо лучше было бы использовать синтаксис и семантику Visual Basic, где в case -выражениях допускается список, каждое из выражений которого может задавать диапазон значений.
Разбор случаев - это часто встречающаяся ситуация в самых разных задачах. Применяя case -ветвь оператором break, но не применяйте
Когда разбор случаев предполагает проверку попадания в некоторый диапазон значений, приходится прибегать к Testing:
/// <summary>
/// Определяет период в зависимости от возраста - age
/// Использование ветвящегося оператора if
/// </summary>
public void SetPeriod()
{
if ((age > 0) (age <7))period=1;
else if ((age >= 7) (age <17))period=2;
else if ((age >= 17) (age <22))period=3;
else if ((age >= 22) (age <27))period=4;
else if ((age >= 27) (age <37))period=5;
else period =6;
}
Этот пример демонстрирует применение ветвящегося period, позволяющую в дальнейшем использовать разбор случаев в зависимости от периода жизни:
/// <summary>
/// Определяет статус в зависимости от периода - period
/// Использование разбора случаев - оператора Switch
/// </summary>
public void SetStatus()
{
switch (period)
{
case 1:
status = "child";
break;
case 2:
status = "schoolboy";
break;
case 3:
status = "student";
break;
case 4:
status = "junior researcher";
break;
case 5:
status = "senior researcher";
break;
case 6:
status = "professor";
break;
default :
status = "не определен";
break;
}
Console.WriteLine("Имя = {0}, Возраст = {1}, Статус = {2}",
name, age, status);
}//SetStatus
Этот пример демонстрирует корректный стиль использования case - ветвей для организации списка выражений одного варианта:
/// <summary>
/// Разбор случаев с использованием списков выражений
/// </summary>
/// <param name="operation">операция над аргументами</param>
/// <param name="arg1">первый аргумент бинарной операции</param>
/// <param name="arg2">второй аргумент бинарной операции</param>
/// <param name="result">результат бинарной операции</param>
public void ExprResult(string operation,int arg1, int arg2,
ref int result)
{
switch (operation)
{
case "+":
case "Plus":
case "Плюс":
result = arg1 + arg2;
break;
case "-":
case "Minus":
case "Минус":
result = arg1 - arg2;
break;
case "*":
case "Mult":
case "Умножить":
result = arg1 * arg2;
break;
case "/":
case "Divide":
case "Div":
case "разделить":
case "Делить":
result = arg1 / arg2;
break;
default:
result = 0;
Console.WriteLine("Операция не определена");
break;
}
Console.WriteLine ("{0} ({1}, {2}) = {3}",
operation, arg1, arg2, result);
}//ExprResult
goto [метка|case константное_выражение|default];
Все операторы языка C# могут иметь метку - уникальный идентификатор, предшествующий оператору и отделенный от него символом двоеточия. Передача управления помеченному оператору - это классическое использование default - ветвь ) используются в
"О вреде
Я уже многие годы не применяю этот оператор и считаю, что хороший стиль программирования не предполагает использования этого оператора в C# ни в каком из вариантов - ни в |
В структурном программировании признаются полезными "переходы вперед" (но не назад), позволяющие при выполнении некоторого условия выйти из цикла, из break и continue.
Оператор break может стоять в теле цикла или завершать case - ветвь в break в теле цикла завершается выполнение самого внутреннего цикла. В теле цикла, чаще всего, оператор break помещается в одну из ветвей
public void Jumps()
{
int i = 1, j=1;
for(i =1; i<100; i++)
{
for(j = 1; j<10;j++)
{
if (j>=3) break;
}
Console.WriteLine("Выход из цикла j при j = {0}", j);
if (i>=3) break;
}
Console.WriteLine("Выход из цикла i при i= {0}", i);
}//Jumps
Оператор continue используется только в теле цикла. В отличие от оператора break, завершающего внутренний цикл, continue осуществляет переход к следующей итерации этого цикла.
Еще одним оператором, относящимся к группе return, позволяющий завершить выполнение процедуры или функции. Его синтаксис:
return [выражение];
Для функций его присутствие и аргумент обязательны, поскольку выражение в операторе return задает значение, возвращаемое функцией.
Без циклов жить нельзя в программах, нет.
Наследованный от С++ весьма удобный
for(инициализаторы; условие; список_выражений) оператор
Оператор, стоящий после закрывающей скобки, задает тело цикла. В большинстве случаев телом цикла является Условие задает условие окончания цикла, соответствующее выражение при вычислении должно получать значение true или false. Список выражений, записанный через запятую, показывает, как меняются счетчики цикла на каждом шаге выполнения. Если условие цикла истинно, то выполняется тело цикла, затем изменяются значения счетчиков и снова проверяется условие. Как только условие становится ложным, цикл завершает свою работу. В цикле
Счетчики цикла зачастую объявляются непосредственно в инициализаторе и соответственно являются переменными, локализованными в цикле, так что после завершения цикла они перестают существовать.
В тех случаях, когда предусматривается возможность преждевременного завершения цикла с помощью одного из
В качестве примера рассмотрим классическую задачу: является ли строка текста палиндромом. Напомню, палиндромом называется симметричная строка текста, читающаяся одинаково слева направо и справа налево. Для ее решения цикл
/// <summary>
/// Определение палиндромов.Демонстрация цикла for
/// </summary>
/// <param name="str">текст</param>
/// <returns>true - если текст является палиндромом</returns>
public bool Palindrom(string str)
{
for (int i =0,j =str.Length-1; i<j; i++,j--)
if(str[i]!=str[j]) return(false);
return(true);
}//Palindrom
while. В языке C# у этого вида цикла две модификации - с проверкой условия в начале и в конце цикла. Первая модификация имеет следующий синтаксис:
while(выражение) оператор
Эта модификация соответствует стратегии: "сначала проверь, а потом делай". В результате проверки может оказаться, что и делать ничего не нужно. Тело такого цикла может ни разу не выполняться. Конечно же, возможно и зацикливание. В нормальной ситуации каждое выполнение тела цикла - это очередной шаг к завершению цикла.
Цикл, проверяющий условие завершения в конце, соответствует стратегии: "сначала делай, а потом проверь". Тело такого цикла выполняется, по меньшей мере, один раз. Вот синтаксис этой модификации:
do оператор while(выражение);
Приведу пример, в котором участвуют обе модификации do while используется для решения уже известной задачи с палиндромами. Вот текст соответствующей процедуры:
/// <summary>
/// Два цикла: с проверкой в конце и в начале.
/// Внешний цикл - образец многократно решаемой задачи.
/// Завершение цикла определяется в диалоге
/// с пользователем.
/// </summary>
public void Loop()
{
string answer, text;
do
{
Console.WriteLine("Введите слово");
text = Console.ReadLine();
int i =0, j = text.Length-1;
while ((i<j) (text[i] == text[j]))
{i++; j--;}
if (text[i] == text[j])
Console.WriteLine(text +" - это палиндром!");
else
Console.WriteLine(text +" - это не палиндром!");
Console.WriteLine("Продолжим? (yes/no)");
answer = Console.ReadLine();
}
while(answer =="yes");
}//Loop
Новым видом цикла, не унаследованным от С++, является
foreach(тип идентификатор in контейнер) оператор
Цикл работает в полном соответствии со своим названием - тело цикла выполняется для каждого элемента в контейнере. Тип идентификатора должен быть согласован с типом элементов, хранящихся в контейнере данных. Предполагается также, что элементы контейнера (массива, коллекции) упорядочены. На каждом шаге цикла идентификатор, задающий текущий элемент контейнера, получает значение очередного элемента в соответствии с порядком, установленным на элементах контейнера. С этим текущим элементом и выполняется тело цикла - выполняется столько раз, сколько элементов находится в контейнере. Цикл заканчивается, когда полностью перебраны все элементы контейнера.
Серьезным недостатком
В приведенном ниже примере показана работа с трехмерным массивом. Массив создается с использованием циклов типа
/// <summary>
/// Демонстрация цикла foreach. Вычисление суммы,
/// максимального и минимального элементов
/// трехмерного массива, заполненного случайными числами.
/// </summary>
public void SumMinMax()
{
int [,,] arr3d = new int[10,10,10];
Random rnd = new Random();
for (int i =0; i<10; i++)
for (int j =0; j<10; j++)
for (int k =0; k<10; k++)
arr3d[i,j,k]= rnd.Next(100);
long sum =0; int min=arr3d[0,0,0], max=arr3d[0,0,0];
foreach(int item in arr3d)
{
sum +=item;
if (item > max) max = item;
else if (item < min) min = item;
}
Console.WriteLine("sum = {0}, min = {1}, max = {2}",
sum, min, max);
}//SumMinMax
Состав операторов языка C#, их синтаксис и семантика унаследованы от языка С++. Как и положено, потомок частично дополнил состав, переопределил синтаксис и семантику отдельных операторов, постарался улучшить характеристики языка во благо программиста. Посмотрим, насколько это удалось языку C#.
Как в языке С++, так и в C#
X = expr;
следует считать настоящим
X1 = X2 = ... = Xk = expr;
В отличие от языка C++ появление
if(x = expr)...
часто используемая в С++, в языке C# в большинстве случаев будет воспринята как ошибка еще на этапе компиляции.
В предыдущих лекциях семантика
С помощью фигурных скобок несколько операторов языка (возможно, перемежаемых объявлениями) можно объединить в единую синтаксическую конструкцию, называемую
{
оператор_1
...
оператор_N
}
В языках программирования нет общепринятой нормы для использования символа точки с запятой при записи последовательности операторов. Есть три различных подхода и их вариации. Категорические противники точек с запятой считают, что каждый оператор должен записываться на отдельной строке (для длинных операторов определяются правила переноса). В этом случае точки с запятой (или другие аналогичные разделители) не нужны. Горячие поклонники точек с запятой (к ним относятся языки С++ и C#) считают, что точкой с запятой должен оканчиваться каждый оператор. В результате в |
Синтаксически
/// <summary>
/// демонстрация блоков (составных операторов)
/// </summary>
public void Block()
{
int limit = 100;
int x = 120, y = 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; y += step;}
else
{x += step; y -= step;}
sum1 += x; sum2 +=y;
}
//limit = step; //переменная step перестала существовать
//limit = i; // переменная i перестала существовать
Console.WriteLine("x= {0}, y= {1}, sum1 ={2}, sum2 = {3}",
x,y,sum1,sum2);
}
Заметьте, здесь в тело основного i и step.
В свою очередь, в тело цикла вложены then и else
Приведенная процедура Block является методом класса Testing, который входит в проект Statements, созданный для работы с примерами этой лекции. Вот описание полей и конструктора класса Testing:
/// <summary>
/// Класс Testing - тестирующий класс. Представляет набор
/// скалярных переменных и методов, тестирующих работу
/// с операторами, процедурами и функциями C#.
/// </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# для выбора одной из нескольких возможностей используются две конструкции -
Начнем с синтаксиса
if(выражение_1) оператор_1 else if(выражение_2) оператор_2 ... else if(выражение_K) оператор_K else оператор_N
Какие особенности синтаксиса следует отметить? Выражения true или false. Напомню, арифметический тип не имеет явных или неявных преобразований к булевому типу. По правилам синтаксиса языка С++, then -ветвь оператора следует сразу за круглой скобкой без ключевого слова then, типичного для большинства языков программирования. Каждый из операторов может быть
if(выражение1) if(выражение2) if(выражение3) ...
Ветви else и else -ветвь. В этом случае краткая форма then -оператор.
Семантика true, проверка прекращается и выполняется оператор (это может быть true. С завершением этого оператора завершается и else, если она есть, относится к ближайшему открытому
Частным, но важным случаем выбора из нескольких вариантов является ситуация, при которой выбор варианта определяется значениями некоторого выражения. Соответствующий оператор C#, унаследованный от C++, но с небольшими изменениями в синтаксисе, называется
switch(выражение)
{
case константное_выражение_1: [операторы_1 оператор_перехода_1]
...
case константное_выражение_K: [операторы_K оператор_перехода_K]
[default: операторы_N оператор_перехода_N]
}
Ветвь default может отсутствовать. Заметьте, по синтаксису допустимо, чтобы после двоеточия следовала пустая последовательность операторов, а не последовательность, заканчивающаяся
Семантика switch -выражения. Затем оно поочередно в порядке следования case сравнивается на совпадение с константными выражениями. Как только достигнуто совпадение, выполняется соответствующая последовательность операторов case -ветви. Поскольку последний оператор этой последовательности является break ), то обычно он завершает выполнение case -ветви, которая, в свою очередь, может передать управление еще куда-нибудь, получая блюдо "спагетти" вместо хорошо структурированной последовательности операторов. Семантика осложняется еще и тем, что case -ветвь может быть пустой последовательностью операторов. Тогда в случае совпадения константного выражения этой ветви со значением switch -выражения будет выполняться первая непустая последовательность очередной case -ветви. Если значение switch -выражения не совпадает ни с одним константным выражением, то выполняется последовательность операторов ветви default, если же таковой ветви нет, то
Полагаю, что |
Еще одна неудача в синтаксической конструкции case -выражения, которые могут быть только константным выражением. Уж если изменять оператор, то гораздо лучше было бы использовать синтаксис и семантику Visual Basic, где в case -выражениях допускается список, каждое из выражений которого может задавать диапазон значений.
Разбор случаев - это часто встречающаяся ситуация в самых разных задачах. Применяя case -ветвь оператором break, но не применяйте
Когда разбор случаев предполагает проверку попадания в некоторый диапазон значений, приходится прибегать к Testing:
/// <summary>
/// Определяет период в зависимости от возраста - age
/// Использование ветвящегося оператора if
/// </summary>
public void SetPeriod()
{
if ((age > 0) (age <7))period=1;
else if ((age >= 7) (age <17))period=2;
else if ((age >= 17) (age <22))period=3;
else if ((age >= 22) (age <27))period=4;
else if ((age >= 27) (age <37))period=5;
else period =6;
}
Этот пример демонстрирует применение ветвящегося period, позволяющую в дальнейшем использовать разбор случаев в зависимости от периода жизни:
/// <summary>
/// Определяет статус в зависимости от периода - period
/// Использование разбора случаев - оператора Switch
/// </summary>
public void SetStatus()
{
switch (period)
{
case 1:
status = "child";
break;
case 2:
status = "schoolboy";
break;
case 3:
status = "student";
break;
case 4:
status = "junior researcher";
break;
case 5:
status = "senior researcher";
break;
case 6:
status = "professor";
break;
default :
status = "не определен";
break;
}
Console.WriteLine("Имя = {0}, Возраст = {1}, Статус = {2}",
name, age, status);
}//SetStatus
Этот пример демонстрирует корректный стиль использования case - ветвей для организации списка выражений одного варианта:
/// <summary>
/// Разбор случаев с использованием списков выражений
/// </summary>
/// <param name="operation">операция над аргументами</param>
/// <param name="arg1">первый аргумент бинарной операции</param>
/// <param name="arg2">второй аргумент бинарной операции</param>
/// <param name="result">результат бинарной операции</param>
public void ExprResult(string operation,int arg1, int arg2,
ref int result)
{
switch (operation)
{
case "+":
case "Plus":
case "Плюс":
result = arg1 + arg2;
break;
case "-":
case "Minus":
case "Минус":
result = arg1 - arg2;
break;
case "*":
case "Mult":
case "Умножить":
result = arg1 * arg2;
break;
case "/":
case "Divide":
case "Div":
case "разделить":
case "Делить":
result = arg1 / arg2;
break;
default:
result = 0;
Console.WriteLine("Операция не определена");
break;
}
Console.WriteLine ("{0} ({1}, {2}) = {3}",
operation, arg1, arg2, result);
}//ExprResult
goto [метка|case константное_выражение|default];
Все операторы языка C# могут иметь метку - уникальный идентификатор, предшествующий оператору и отделенный от него символом двоеточия. Передача управления помеченному оператору - это классическое использование default - ветвь ) используются в
"О вреде
Я уже многие годы не применяю этот оператор и считаю, что хороший стиль программирования не предполагает использования этого оператора в C# ни в каком из вариантов - ни в |
В структурном программировании признаются полезными "переходы вперед" (но не назад), позволяющие при выполнении некоторого условия выйти из цикла, из break и continue.
Оператор break может стоять в теле цикла или завершать case - ветвь в break в теле цикла завершается выполнение самого внутреннего цикла. В теле цикла, чаще всего, оператор break помещается в одну из ветвей
public void Jumps()
{
int i = 1, j=1;
for(i =1; i<100; i++)
{
for(j = 1; j<10;j++)
{
if (j>=3) break;
}
Console.WriteLine("Выход из цикла j при j = {0}", j);
if (i>=3) break;
}
Console.WriteLine("Выход из цикла i при i= {0}", i);
}//Jumps
Оператор continue используется только в теле цикла. В отличие от оператора break, завершающего внутренний цикл, continue осуществляет переход к следующей итерации этого цикла.
Еще одним оператором, относящимся к группе return, позволяющий завершить выполнение процедуры или функции. Его синтаксис:
return [выражение];
Для функций его присутствие и аргумент обязательны, поскольку выражение в операторе return задает значение, возвращаемое функцией.
Без циклов жить нельзя в программах, нет.
Наследованный от С++ весьма удобный
for(инициализаторы; условие; список_выражений) оператор
Оператор, стоящий после закрывающей скобки, задает тело цикла. В большинстве случаев телом цикла является Условие задает условие окончания цикла, соответствующее выражение при вычислении должно получать значение true или false. Список выражений, записанный через запятую, показывает, как меняются счетчики цикла на каждом шаге выполнения. Если условие цикла истинно, то выполняется тело цикла, затем изменяются значения счетчиков и снова проверяется условие. Как только условие становится ложным, цикл завершает свою работу. В цикле
Счетчики цикла зачастую объявляются непосредственно в инициализаторе и соответственно являются переменными, локализованными в цикле, так что после завершения цикла они перестают существовать.
В тех случаях, когда предусматривается возможность преждевременного завершения цикла с помощью одного из
В качестве примера рассмотрим классическую задачу: является ли строка текста палиндромом. Напомню, палиндромом называется симметричная строка текста, читающаяся одинаково слева направо и справа налево. Для ее решения цикл
/// <summary>
/// Определение палиндромов.Демонстрация цикла for
/// </summary>
/// <param name="str">текст</param>
/// <returns>true - если текст является палиндромом</returns>
public bool Palindrom(string str)
{
for (int i =0,j =str.Length-1; i<j; i++,j--)
if(str[i]!=str[j]) return(false);
return(true);
}//Palindrom
while. В языке C# у этого вида цикла две модификации - с проверкой условия в начале и в конце цикла. Первая модификация имеет следующий синтаксис:
while(выражение) оператор
Эта модификация соответствует стратегии: "сначала проверь, а потом делай". В результате проверки может оказаться, что и делать ничего не нужно. Тело такого цикла может ни разу не выполняться. Конечно же, возможно и зацикливание. В нормальной ситуации каждое выполнение тела цикла - это очередной шаг к завершению цикла.
Цикл, проверяющий условие завершения в конце, соответствует стратегии: "сначала делай, а потом проверь". Тело такого цикла выполняется, по меньшей мере, один раз. Вот синтаксис этой модификации:
do оператор while(выражение);
Приведу пример, в котором участвуют обе модификации do while используется для решения уже известной задачи с палиндромами. Вот текст соответствующей процедуры:
/// <summary>
/// Два цикла: с проверкой в конце и в начале.
/// Внешний цикл - образец многократно решаемой задачи.
/// Завершение цикла определяется в диалоге
/// с пользователем.
/// </summary>
public void Loop()
{
string answer, text;
do
{
Console.WriteLine("Введите слово");
text = Console.ReadLine();
int i =0, j = text.Length-1;
while ((i<j) (text[i] == text[j]))
{i++; j--;}
if (text[i] == text[j])
Console.WriteLine(text +" - это палиндром!");
else
Console.WriteLine(text +" - это не палиндром!");
Console.WriteLine("Продолжим? (yes/no)");
answer = Console.ReadLine();
}
while(answer =="yes");
}//Loop
Новым видом цикла, не унаследованным от С++, является
foreach(тип идентификатор in контейнер) оператор
Цикл работает в полном соответствии со своим названием - тело цикла выполняется для каждого элемента в контейнере. Тип идентификатора должен быть согласован с типом элементов, хранящихся в контейнере данных. Предполагается также, что элементы контейнера (массива, коллекции) упорядочены. На каждом шаге цикла идентификатор, задающий текущий элемент контейнера, получает значение очередного элемента в соответствии с порядком, установленным на элементах контейнера. С этим текущим элементом и выполняется тело цикла - выполняется столько раз, сколько элементов находится в контейнере. Цикл заканчивается, когда полностью перебраны все элементы контейнера.
Серьезным недостатком
В приведенном ниже примере показана работа с трехмерным массивом. Массив создается с использованием циклов типа
/// <summary>
/// Демонстрация цикла foreach. Вычисление суммы,
/// максимального и минимального элементов
/// трехмерного массива, заполненного случайными числами.
/// </summary>
public void SumMinMax()
{
int [,,] arr3d = new int[10,10,10];
Random rnd = new Random();
for (int i =0; i<10; i++)
for (int j =0; j<10; j++)
for (int k =0; k<10; k++)
arr3d[i,j,k]= rnd.Next(100);
long sum =0; int min=arr3d[0,0,0], max=arr3d[0,0,0];
foreach(int item in arr3d)
{
sum +=item;
if (item > max) max = item;
else if (item < min) min = item;
}
Console.WriteLine("sum = {0}, min = {1}, max = {2}",
sum, min, max);
}//SumMinMax
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.