C#. Цикл foreach. Назначение. Примеры использования




Цикл foreach. Назначение. Примеры использования


Содержание


Поиск на других ресурсах:

1. Назначение цикла foreach. Общая форма

Оператор цикла foreach предназначен для перебора элементов коллекции или массива. Общая форма оператора foreach следующая

foreach(type identifier in container)
{
  // операторы
  // ...
}

где

  • type – тип переменной с именем identifier;
  • identifier – имя переменной, которая используется в качестве итератора. Переменная identifier приобретает значение следующего элемента цикла на каждом шаге выполнения цикла foreach. Тип переменной identifier должен совпадать с типом массива или коллекции container. Связь между identifier и container реализуется с помощью союза in;
  • container – имя коллекции или массива, который просматривается.

Оператор цикла foreach работает следующим образом. При вхождении в цикл, переменной identifier присваивается первый элемент массива (коллекции) container. На каждом следующем шаге итерации выбирается следующий элемент из container, который сохраняется в переменной identifier. Цикл завершается, когда будут пересмотрены все элементы массива (коллекции) container.

 

2. Примеры использования оператора цикла foreach для массивов
2.1. Вычисление суммы элементов массива типа double

 В примере решена задача вычисления суммы элементов массива типа double. Текст программы, созданный по шаблону Console Application следующий.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      // объявить массив типа double, выделить память для массива
      double[] A = new double[10];
      Random rnd_num = new Random();

      // заполнить массив случайными числами в диапазоне от 0 до 20
      for (int i = 0; i < A.Length; i++)
      {
        A[i] = rnd_num.NextDouble() * 20;
      }

      // вывести массив для проверки
      Console.WriteLine("Array A:");
      for (int i = 0; i < A.Length; i++)
      {
        Console.Write("{0:f3} ", A[i]);
      }
      Console.WriteLine();

      // Использование цикла foreach для вычисления суммы элементов массива
      double summ = 0;
      foreach (double item in A)
      {
        summ += item;
      }

      Console.WriteLine("summ = {0:f3}", summ);
      Console.ReadKey();
    }
  }
}

 Результат работы программы

Array A:
7,117 1,218 9,963 13,038 17,656 9,593 5,876 9,802 3,305 2,546
summ = 80,114


 

2.2. Поиск максимального значения в массиве

В примере продемонстрирован обход целочисленного массива с помощью оператора цикла foreach.

Пример.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      // массив из 10 чисел типа int
      int[] A = new int[10];
      int max = 0; // искомое максимальное значение
      bool f_first; // первый элемент в массиве
      Random rnd_num = new Random(); // случайное число

      // 1. Заполнить массив случайными числами
      for (int i = 0; i < A.Length; i++)
      {
        A[i] = rnd_num.Next(0, 20);
      }

      // 2. Вывод массива для контроля
      for (int i = 0; i < A.Length; i++)
        Console.Write("{0} ", A[i]);
      Console.WriteLine();

      // 3. Цикл foreach
      f_first = true; // признак первого элемента в массиве

      foreach (int item in A)
      {
        if (f_first) // если первый элемент в массиве
        {
          max = item; // то запомнить его
          f_first = false;
        }
        else
        {
          if (max < item)
            max = item;
        }
      }

      // 3. Вывод результата
      Console.WriteLine("max = {0}", max);
      Console.ReadKey();
    }
  }
}

Результат работы программы

3 10 4 15 3 1 6 10 15 14
max = 15

 

3. Примеры использования цикла foreach для коллекций
3.1. Пример работы с коллекцией ArrayList. Определение минимального элемента в коллекции вещественных чисел

Текст программы для приложения типа Console Application следующий

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      // Цикл foreach, коллекция ArrayList
      ArrayList AL = new ArrayList(); // создать коллекцию из 10 элементов
      Random rnd_num = new Random();

      // 1. Записать в коллекцию случайные вещественные числа от 0 до 10
      for (int i = 0; i < 10; i++)
      {
        AL.Add(rnd_num.NextDouble() * 10); // добавить число
      }

      // 2. Вывести коллекцию на экран для проверки, использовать цикл foreach
      foreach (double x in AL)
      {
        Console.Write("{0:f2} ", x);
      }
      Console.WriteLine();

      // 3. Определение минимального элемента коллекции
      double min = 0;
      bool f_first = true;

      foreach (double x in AL)
      {
        if (f_first)
        {
          min = x;
          f_first = false;
        }
        else
        {
          if (min > x) min = x;
        }
      }

      // 4. Вывод результата
      Console.WriteLine("min = {0:f2}", min);

      Console.ReadKey();
    }
  }
}

Результат работы программы

8,13 7,47 3,23 5,98 9,43 1,65 0,27 7,82 0,79 2,85
min = 0,27

 

3.2. Пример работы с коллекцией Hashtable

В примере реализован поиск данных по заданному ключу с помощью цикла foreach. Поиск реализован для данных коллекции типа Hashtable. Сначала формируется массив ключей типа int и значений типа double, соответствующих этим ключам.

Текст приложения типа Console Application следующий

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Collections;

namespace ConsoleApp8
{
  class Program
  {
    static void Main(string[] args)
    {
      // Цикл foreach, коллекция Hashtable
      Hashtable ht = new Hashtable(); // создать коллекцию
      Random rnd_value = new Random(); // случайное значение
      int key;
      double value;

      // 1. Цикл формирования ключей и записей
      for (int i = 0; i < 8; i++)
      {
        key = i; // получить ключ
        value = rnd_value.NextDouble(); // взять случайное значение
        ht.Add(key, value); // добавить в таблицу
      }

      // 2. Вывести таблицу на экран
      // Цикл foreach
      ICollection ic = ht.Keys; // получить коллекцию ключей
      foreach (Object k in ic) // использовать ключ для поиска значения
      {
        // вывести пару ключ-значение
        Console.Write("{0}-{1:f1}, ", k, ht[k]);
      }
      Console.WriteLine();

      // 3. Ввод ключа, по которому нужно получить данные
      int fkey;

      Console.Write("Enter key: ");
      fkey = Convert.ToInt32(Console.ReadLine());

      // 4. Поиск данных по ключу, цикл foreach
      bool f_find = false;

      foreach (Object k in ic) // перебор ключей
      {
        if ((int)k == fkey) // найден ли ключ?
        {
          value = (double)ht[k]; // получить значение по ключу
          f_find = true;
          Console.WriteLine("Key = {0}, data = {1:f1}", k, value);
          break; // данные найдены, не имеет смысла продолжать цикл
        }
      }

      if (!f_find)
        Console.WriteLine("Key is wrong.");
      Console.ReadKey();
    }
  }
}

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

7-0.3, 6-0.5, 5-0.0, 4-0.6, 3-0.9, 2-0.8, 1-0.6, 0-1.0,
Enter key: 4
Key = 4, data = 0.6

 

4. Применение оператора foreach для двумерного массива

Оператор цикла foreach может использоваться для двумерных и многомерных массивов. В этом случае элементы массива рассматриваются в порядке чтения строк, от первой к последней.

В примере вычисляется сумма элементов двумерного массива типа float.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Collections;

namespace ConsoleApp8
{
  class Program
  {
    static void Main(string[] args)
    {
      // 1. Создать двумерный массив
      float[,] AF = new float[3, 4];
      float sum = 0; // искомая сумма

      // 2. Заполнить массив значениями
      Random rnd_num = new Random();

      for (int i = 0; i < 3; i++)
        for (int j = 0; j < 4; j++)
        {
          AF[i, j] = (float)rnd_num.NextDouble() * 5; // числа от 0 до 5
        }

      // 3. Вывести массив для проверки
      Console.WriteLine("Array AF: ");
      for (int i = 0; i < 3; i++)
      {
        for (int j = 0; j < 4; j++)
          Console.Write("{0:f1} ", AF[i, j]);
        Console.WriteLine();
      }

      // 4. Вычислить сумму с помощью цикла foreach
      foreach (float x in AF)
      {
        sum += x;
      }

      // 5. Вывести сумму
      Console.WriteLine("summ = {0:f1}", sum);

      Console.ReadKey();
    }
  }
}

Результат работы программы

Array AF:
1.5 0.5   2.3 4.2
0.6 4.3   1.4 3.7
1.2 4.9   1.9 4.4
summ = 31.0

 

5. Особенности применения оператора break в цикле foreach. Пример

С помощью оператора break можно прервать выполнение цикла foreach. Как правило, прерывание цикла осуществляется при выполнении некоторого условия.

Пример. Поиск в массиве заданного числа.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      // Поиск в массиве заданного числа
      // объявить массив типа int, выделить память для массива
      int[] A = new int[10];
      int number; // число, которое нужно найти в массиве A
      Random rnd_num = new Random(); // экземпляр класса Random

      // Сформировать массив A случайно
      for (int i = 0; i < A.Length; i++)
        A[i] = rnd_num.Next(0, 20);

      Console.WriteLine("Array A: ");

      // Вывести массив A
      for (int i = 0; i < A.Length; i++)
        Console.Write("{0} ", A[i]);
      Console.WriteLine();

      // Ввести число, которое нужно проверить
      Console.Write("Enter number: ");
      number = Convert.ToInt32(Console.ReadLine());

      // Использование цикла foreach и оператора break
      bool f_is = false;
      foreach (int item in A)
      {
        if (number == item)
        {
          f_is = true;
          break; // выход из цикла, дальнейшее выполнение цикла не имеет смысла
        }
      }

      if (f_is)
        Console.WriteLine("Item {0} is in array A.", number);
      else
        Console.WriteLine("Item {0} is not in array A.", number);

      Console.ReadKey();
    }
  }
}

В вышеприведенной программе продемонстрировано использование оператора break в цикле foreach. Как только искомое значение number встретится в массиве A, то нет смысла выполнять дальнейшие итерации.

Результат работы программы

Array A:
11 15 13 6 4 18 8 18 0 4
Enter number: 8
Item 8 is in array A.

 

6. Применение оператора foreach со строками. Пример

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

Текст программы, созданной по шаблону Console Application следующий

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Collections;

namespace ConsoleApp8
{
  class Program
  {
    static void Main(string[] args)
    {
      // Подсчет заданного символа в тексте
      string str;
      char symbol;
      int count = 0; // количество символов

      // 1. Ввести текст
      Console.WriteLine("Enter text: ");
      str = Console.ReadLine();

      // 2. Ввести символ
      Console.Write("Enter symbol: ");
      symbol = (char)Console.Read();

      // 3. Использование цикла foreach
      foreach(char c in str)
        if (c == symbol) count++;

      // 4. Вывести результат
      Console.WriteLine("count = {0}", count);

      Console.ReadKey();
    }
  }
}

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

Enter text:
bestprog.net
Enter symbol: t
count = 2

 

7. Вложенные циклы foreach. Пример

Циклы foreach могут быть вложенными.

Пример. Задан массив строк. В массиве нужно строк подсчитать количество символов ‘+’.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Collections;

namespace ConsoleApp8
{
  class Program
  {
    static void Main(string[] args)
    {
      // Вычисление количества вхождений символа '+' в массиве строк
      string[] S; // ссылка на массив строк
      int count;

      // 1. Ввести количество строк
      Console.Write("Enter number of strings: ");
      count = Convert.ToInt32(Console.ReadLine());

      // 2. Выделение памяти для массива строк
      S = new string[count];

      // 3. Ввести строки
      Console.WriteLine("Enter strings: ");
      for (int i = 0; i < count; i++)
        S[i] = Console.ReadLine();

      // 4. Вычисление с использованием вложенных циклов foreach
      count = 0;
      foreach (string str in S) // перебор строк
      {
        foreach (char c in str) // перебор символов в строке
        {
          if (c == '+')
            count++;
        }
      }

      Console.WriteLine("count = {0}", count);
      Console.ReadKey();
    }
  }
}

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

Enter number of strings: 4
Enter strings:
a+5=25
b-8-c+d = 333
c+d+f*d=248
abc+def=abcdef
count = 5

 

8. Преимущества и недостатки оператора цикла foreach по сравнению с другими операторами цикла

Можно выделить следующие преимущества цикла foreach:

  • упрощенность синтаксической конструкции цикла;
  • переменной-итератору не нужно задавать начальное значение, указывать прирост;
  • не нужно указывать условие завершения цикла.

Недостатки:

  • нельзя пересматривать элементы массива или коллекции в обратном порядке;
  • переменная-итератор не может рассматривать выборочные элементы массива или коллекции, например, рассматривать элементы коллекции, которые лежат на парных позициях. Однако, этот недостаток есть условным, поскольку можно использовать разные дополнительные переменные (флажки) для получения доступа к нужным элементам.

 


Связанные темы