- Цикл for в C#
- Цикл for
- Синтаксис цикла
- Как работает цикл for
- Блок-схема работы цикла
- Пример 1. Итерации цикла for
- Пример 2. Вычисляем сумму первых n натуральных чисел
- Несколько выражений внутри цикла for
- Пример 3. Цикл for с несколькими выражениями
- Цикл for без объявления счетчика и итератора
- Пример 4. Цикл for без объявления счетчика и итератора
- Бесконечный цикл for
- Пример 5. Бесконечный цикл for
- Операторы итерации — for , foreach , do и while
- Инструкция for
- Инструкция foreach
- await foreach
- Тип переменной итерации
- Инструкция do
- Инструкция while
- Спецификация языка C#
- См. также
Цикл for в C#
В программировании порой необходимо выполнить набор инструкций определенное количество раз. Возможное решение — скопировать код. Но есть проблема: количество этих наборов мы можем либо не знать, либо их может быть очень много (10000, к примеру).
Решение проблемы — циклы. В программировании циклы используются для многократного выполнения блока кода. Цикл работает до тех пор, пока заданное условие истинно.
Цикл for
Для инициализации цикла используется ключевое слово for.
Синтаксис цикла
for (счетчик; условие; итератор)
// тело цикла
>
Как работает цикл for
- В цикле for три переменные: счетчик , условие и итератор .
- Объявление счетчика происходит в самом начале и лишь раз. Обычно он инициализируется сразу после объявления.
- Затем проверяется условие. Условие — булево выражение. То есть, возвращает true или false .
- Если условие определяется как true :
• Выполняются инструкции внутри цикла.
• После этого инициализируется итератор — обычно изменяется значение этой переменной.
• Условие проверяется снова.
• Процесс повторяется до тех пор, пока условие не будет определено как false . - Если условие определится как false , цикл завершается.
Блок-схема работы цикла
Пример 1. Итерации цикла for
using System; namespace Loop < class ForLoop < public static void Main(string[] args) < for (int i=1; i", i); > > > >
Цикл for C#: итерация 1
Цикл for C#: итерация 2
Цикл for C#: итерация 3
Цикл for C#: итерация 4
Цикл for C#: итерация 5
После запуска программы происходит следующее:
- Объявляется и инициализируется переменная i . Ей присваивается значение 1.
- После этого проверяется условие i
- Если проверка условия возвращает `true`, выполняется тело цикла. Оно печатает строку «Цикл for C#: итерация 1».
- Затем определяется значение итератора ( i++ ). Значение i увеличивается до 2.
- Условие ( i
- Когда значение i станет равняться 6, условие оценится как false . Следовательно, цикл завершится.
Пример 2. Вычисляем сумму первых n натуральных чисел
using System; namespace Loop < class ForLoop < public static void Main(string[] args) < int n = 5, sum = 0; for (int i=1; iConsole.WriteLine("Сумма первых натуральных чисел = ", n, sum); > > >
Сумма первых 5 натуральных чисел = 15
В этой программе объявляются две переменные — sum и n . Их значения равны 0 и 5 соответственно. Значение счетчика i в самом начале равно 1.
Внутри цикла значение переменной sum увеличивается на i — sum = sum + i . Цикл продолжается до тех пор, пока значение счетчика i меньше или равно n .
Давайте посмотрим, что происходит на каждой итерации цикла.
Изначально i = 1, sum = 0 и n = 5.
Значение sum
То есть, финальное значение sum будет равняться 15.
Несколько выражений внутри цикла for
Внутри цикла for может быть несколько выражений. Это значит, что мы можем инициализировать несколько счетчиков и итераторов. Давайте разберем следующий пример.
Пример 3. Цикл for с несколькими выражениями
using System; namespace Loop < class ForLoop < public static void Main(string[] args) < for (int i=0, j=0; i+jи j = ", i,j); > > > >
i = 0 и j = 0 i = 1 и j = 1 i = 2 и j = 2
В этой программе мы объявили и инициализировали 2 переменных-счетчика — i и j .
В части итератора у нас также два выражения. То есть, на каждой итерации цикла i и j увеличиваются на 1.
Цикл for без объявления счетчика и итератора
Объявление счетчика, условия и итератора в цикле for не обязательно. Запустить цикл for мы можем и без них.
В таких случаях цикл for работает так же, как и while. Давайте рассмотрим.
Пример 4. Цикл for без объявления счетчика и итератора
using System; namespace Loop < class ForLoop < public static void Main(string[] args) < int i = 1; for ( ; i", i); i++; > > > >
Цикл for C#: итерация 1
Цикл for C#: итерация 2
Цикл for C#: итерация 3
Цикл for C#: итерация 4
Цикл for C#: итерация 5
В этом примере мы не объявляли счетчик и итератор.
Переменная i объявлена до цикла for и ее значение увеличивается внутри тела цикла. Эта программа практически идентична той, о которой мы говорили в первом примере.
Условие цикла также является необязательным параметром. Но без условия цикл будет бесконечным.
Бесконечный цикл for
Если условие выполнения цикла всегда true , то он будет выполняться бесконечно. Это называется бесконечным циклом.
Пример 5. Бесконечный цикл for
using System; namespace Loop < class ForLoop < public static void Main(string[] args) < for (int i=1 ; i >0; i++) < Console.WriteLine("Цикл for C#: итерация ", i); > > > >
В этом примере i было присвоено значение 1. Условие — i > 0 . На каждой итерации цикла значение `i` увеличивается на 1. Из-за этого условие цикла никогда не примет значение false . Именно поэтому цикл будет выполняться бесконечно.
Инициализировать бесконечный цикл можно и заменой условия пробелом. Например:
for (счетчик; ; итератор)
// тело цикла
>
Операторы итерации — for , foreach , do и while
Операторы итерации многократно выполняют инструкцию или блок инструкций. Оператор for выполняет свой текст, в то время как указанное логическое выражение принимает значение true . Оператор foreach перечисляет элементы коллекции и выполняет ее текст для каждого элемента коллекции. Оператор do условно выполняет свой текст один или несколько раз. Оператор while условно выполняет свой текст ноль или более раз.
В любой момент в теле оператора итерации можно вырваться из цикла с помощью break оператора . Вы можете перейти к следующей итерации в цикле continue с помощью оператора .
Инструкция for
Оператор for выполняет оператор или блок операторов, пока определенное логическое выражение равно значению true . В следующем примере показана инструкция for , выполняющая тело пока целочисленный счетчик меньше трех:
for (int i = 0; i < 3; i++) < Console.Write(i); >// Output: // 012
В предыдущем примере показаны элементы оператора for :
- Раздел инициализатора, который выполняется только один раз перед входом в цикл. Как правило, в этом разделе объявляется и инициализируется локальная переменная цикла. Доступ к объявленной переменной извне оператора for невозможен. В разделе инициализатора в предыдущем примере объявляется и инициализируется целочисленная переменная-счетчик:
Раздел итератора может содержать ноль или более следующих выражений оператора, разделенных запятыми:
- префиксное или постфиксное выражение приращения, такое как ++i или i++
- префиксное или постфиксное выражение декремента, такое как —i или i—
- присваивание
- вызов метода
- Выражение
- создание объекта с помощью new оператора
Если переменная цикла не объявлена в разделе инициализатора, в разделе инициализатора можно также использовать ноль или более выражений из предыдущего списка. В следующем примере показано несколько менее распространенных вариантов использования разделов инициализатора и итератора: присваивание значения внешней переменной цикла в разделе инициализатора, вызов метода в разделах инициализатора и итератора и изменение значения двух переменных в разделе итератора.
int i; int j = 3; for (i = 0, Console.WriteLine($"Start: i=, j="); i < j; i++, j--, Console.WriteLine($"Step: i=, j=")) < //. >// Output: // Start: i=0, j=3 // Step: i=1, j=2 // Step: i=2, j=1
Все разделы оператора for необязательны. Например, в следующем коде определяется бесконечный цикл for :
Инструкция foreach
Оператор foreach выполняет оператор или блок операторов для каждого элемента в экземпляре типа, который реализует интерфейс System.Collections.IEnumerable или System.Collections.Generic.IEnumerable , как показано в следующем примере.
var fibNumbers = new List < 0, 1, 1, 2, 3, 5, 8, 13 >; foreach (int element in fibNumbers) < Console.Write($""); > // Output: // 0 1 1 2 3 5 8 13
Оператор foreach не ограничен этими типами. Его можно использовать с экземпляром любого типа, который удовлетворяет следующим условиям:
- Тип имеет открытый метод без параметров GetEnumerator . Начиная с C# 9.0 метод GetEnumerator может быть методом расширения типа.
- тип возвращаемого значения метода GetEnumerator должен содержать открытое свойство Current и открытый метод MoveNext без параметров с типом возвращаемого значения bool .
В следующем примере показано использование оператора foreach с экземпляром типа System.Span , который не реализует интерфейс:
Span numbers = new int[] < 3, 14, 15, 92, 6 >; foreach (int number in numbers) < Console.Write($""); > // Output: // 3 14 15 92 6
Если свойство перечислителя Current возвращает возвращаемое значение ссылки ( ref T где T — это тип элемента коллекции), можно объявить переменную итерации с модификатором ref или ref readonly , как показано в следующем примере:
Span storage = stackalloc int[10]; int num = 0; foreach (ref int item in storage) < item = num++; >foreach (ref readonly var item in storage) < Console.Write($""); > // Output: // 0 1 2 3 4 5 6 7 8 9
Если исходная коллекция инструкции foreach пуста, тело оператора foreach не выполняется и пропускается. Если оператор foreach применяется к null , возникает исключение NullReferenceException.
await foreach
await foreach (var item in GenerateSequenceAsync())
Оператор await foreach можно также использовать с экземпляром любого типа, который удовлетворяет следующим условиям:
- Тип имеет открытый метод без параметров GetAsyncEnumerator . Этот метод может быть методом расширения типа.
- Тип возвращаемого значения метода GetAsyncEnumerator имеет открытое свойство Current и открытый метод без параметров MoveNextAsync , тип возвращаемого значения которого — Task , ValueTask или любой другой подтверждающий ожидание тип, метод ожидания которого GetResult возвращает значение bool .
Элементы потока по умолчанию обрабатываются в захваченном контексте. Чтобы отключить захват контекста, используйте метод расширения TaskAsyncEnumerableExtensions.ConfigureAwait. Дополнительные сведения о контекстах синхронизации и захвате текущего контекста см. в статье Использование асинхронного шаблона, основанного на задачах. Дополнительные сведения об асинхронных потоках см. в руководстве по асинхронным потокам.
Тип переменной итерации
Можно использовать ключевое слово var , чтобы компилятор мог определить тип переменной итерации в операторе foreach , как показано в следующем коде:
foreach (var item in collection)
Можно также явно указать тип переменной итерации, как показано в следующем коде:
IEnumerable collection = new T[5]; foreach (V item in collection)
В предыдущей форме тип T элемента коллекции должен быть неявно или явно преобразован в тип V переменной итерации. Если явное преобразование из T в V завершается ошибкой во время выполнения, оператор foreach выдает исключение InvalidCastException. Например, если T является незапечатанным типом класса, V может быть любым типом интерфейса, даже тем, который T не реализует. Во время выполнения тип элемента коллекции может быть производным от T и фактически реализовать V . В противном случае возникает InvalidCastException.
Инструкция do
Оператор do выполняет оператор или блок операторов, пока определенное логическое выражение равно значению true . Так как это выражение оценивается после каждого выполнения цикла, цикл do выполняется один или несколько раз. Цикл do отличается от while цикла, который выполняется ноль или более раз.
В следующем примере показано применение оператора do .
Инструкция while
Оператор while выполняет оператор или блок операторов, пока определенное логическое выражение равно значению true . Так как это выражение оценивается перед каждым выполнением цикла, цикл while выполняется ноль или несколько раз. Цикл while отличается от do цикла, который выполняется один или несколько раз.
В следующем примере показано применение оператора while .
int n = 0; while (n < 5) < Console.Write(n); n++; >// Output: // 01234
Спецификация языка C#
Дополнительные сведения см. в следующих разделах статьи Спецификация языка C#:
Дополнительные сведения о функциях, добавленных в C# 8.0 и более поздние версии, см. в следующих заметках о функциях.