Денис Суворов 04 февраля 2022

🧊 Руководство по С# для начинающих: массивы и цикл foreach

Рассмотрим на примерах одномерный, многомерный и ступенчатый массивы, а также цикл foreach для работы с коллекциями и массивами.
🧊 Руководство по С# для начинающих: массивы и цикл foreach

Объявление массива

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

Элементы массива
Элементы массива

В C# массив объявляется следующим образом:

        datatype[] arrayName;
    

Где:

datatype – тип данных, такой как int, string, char и т. д.

arrayName – имя массива (идентификатор).

Пример:

        int[] age;
    

Создан массив с именем age. Этот массив может хранить элементы типа int.

Чтобы определить количество элементов, которые может хранить массив, в C# нужно выделить память для массива.

Пример:

        // объявляем массив
int[] age;

// выделяем память для массива
age = new int[5];
    

new int[5] – означает, что массив хранит 5 элементов. Также можно сказать, что размер или длина массива равны 5.

Примечание
Также можно объявить массив и выделить для него память в одной строке:

Пример:

        int[] age = new int[5];
    
Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека шарписта»

Инициализация массива

В C# можно инициализировать массив в момент объявления.

Пример:

        int [] numbers = {1, 2, 3, 4, 5};
    

В этом примере создан массив с именем numbers и инициализирован значениями 1, 2, 3, 4 и 5 внутри фигурных скобок.

Обратите внимание, что не указан размер массива. В этом случае C# автоматически указывает размер, подсчитывая количество элементов в массиве (т. е. 5).

В массиве используется порядковый номер для определения позиции каждого элемента массива. Также порядковый номер используется при инициализации массива в C#.

Пример:

        // объявляем массив
int[] age = new int[5];

// инициализируем массив
age[0] = 12;
age[1] = 4;
age[2] = 5;
…

    
Инициализация массива в C#
Инициализация массива в C#
Примечание
Индексация массивов в C# начинается с 0. То есть первый элемент массива имеет индекс 0. Если размер массива равен 5, то индекс последнего элемента будет равен 4.

Доступ к элементам массива

Для получения доступа к элементам массива используется индекс массива.

Пример:

        // доступ к элементу по индексу 2
array[2];

// доступ к элементу по индексу 4
array[4];
    

Где:

  • array[2] – третий элемент массива.
  • array[4] – пятый элемент массива.
Пример: C# массив
        using System;

namespace AccessArray {
  class Program  {
    static void Main(string[] args) {

      // создаем массив
      int[] numbers = {1, 2, 3};

      //получаем доступ к первому элементу
      Console.WriteLine("Element in first index : " + numbers[0]);

      //получаем доступ ко второму элементу
      Console.WriteLine("Element in second index : " + numbers[1]);

      //получаем доступ к третьему элементу
      Console.WriteLine("Element in third index : " + numbers[2]);

      Console.ReadLine();

    }
  }
}

    

Вывод:

Element in first index : 1
Element in second index : 2
Element in third index : 3

В примере выше создан массив с именем numbers с элементами 1, 2, 3. Порядковый номер используется для доступа к элементам массива.

Здесь:

  • numbers[0] – доступ к первому элементу.
  • numbers[1] – доступ ко второму элементу.
  • numbers[2] – доступ к третьему элементу.

Изменение элементов массива

Чтобы изменить элемент массива, присвоим новое значение конкретному индексу.

Пример:

        using System;

namespace ChangeArray {
  class Program {
    static void Main(string[] args) {

      // создать массив
      int[] numbers = {1, 2, 3};

      Console.WriteLine("Old Value at index 0: " + numbers[0]);

      // изменить значение по индексу 0
      numbers[0] = 11;

      // вывести на экран новое значение
      Console.WriteLine("New Value at index 0: " + numbers[0]);

      Console.ReadLine();
    }
  }
}

    

Вывод:

Old Value at index 0: 1
New Value at index 0: 11

В примере выше начальное значение с индексом 0 равно 1. Обратите внимание на строчку:

        // изменим значение по индексу 0
numbers[0] = 11;

    

В этой строке присваивается новое значение 11 по индексу 0. И теперь значение по индексу 0 меняется с 1 на 11.

Обход (итерация) массива с помощью циклов

В C# для обхода каждого элемента массива используются циклы.

Пример:

Использование цикла for
        using System;

namespace AccessArrayFor {
  class Program {
    static void Main(string[] args) {

      int[] numbers = { 1, 2, 3};
 	 
      for(int i=0; i < numbers.Length; i++) {
        Console.WriteLine("Element in index " + i + ": " + numbers[i]);
      }

      Console.ReadLine();
    }
  }
}

    

Вывод:

Element in index 0: 1
Element in index 1: 2
Element in index 2: 3

В примере выше используется цикл for для обхода элементов массива numbers. Обратите внимание на строчку:

        numbers.Length
    

Здесь:

Length – свойство, отвечающее за длину массива.

Также для перебора элементов массива используется цикл foreach.

Пример:

Использование цикла foreach
        using System;

namespace AccessArrayForeach {
  class Program {
    static void Main(string[] args) {
      int[] numbers = {1, 2, 3};

      Console.WriteLine("Array Elements: ");

      foreach(int num in numbers) {
        Console.WriteLine(num);
      }

      Console.ReadLine();
    }
  }
}

    

Вывод:

Array Elements:
1
2
3

Операции с массивом с использованием System.Linq

В C# пространство имен System.Linq предоставляет методы для выполнения операций над массивом.

Пример:

Поиск минимального и максимального элемента
        using System;

 // предоставляет методы для работы с массивом
using System.Linq;

namespace ArrayMinMax {
  class Program  {
    static void Main(string[] args) {

      int[] numbers = {51, 1, 3, 4, 98};

      // получить минимальный элемент
      Console.WriteLine("Smallest  Element: " + numbers.Min());  

      // Max() возвращает наибольшее число в массиве
      Console.WriteLine("Largest Element: " + numbers.Max());  
 	 
      Console.ReadLine();
    }
  }
}

    

Вывод:

Smallest Element: 1
Largest Element: 98

В приведенном выше примере:

  • numbers.Min() – возвращает наименьшее число массива, 1.
  • numbers.Max() – возвращает наибольшее число массива, 98.
Поиск среднего в массиве
        using System;
// предоставляет методы для работы с массивом
using System.Linq;

namespace ArrayFunction {
  class Program  {
    static void Main(string[] args) {

      int[] numbers = {30, 31, 94, 86, 55};
 	 
      // получение суммы элементов массива
      float sum = numbers.Sum();
 	 
      // получение количества элементов в массиве
      int count = numbers.Count();
 	 
      float average = sum/count;

      Console.WriteLine("Average : " + average);
 	
      // расчет среднего
      Console.WriteLine("Average using Average() : " + numbers.Average());
 	 
      Console.ReadLine();
    }
  }
}

    

Вывод:

Average : 59.2
Average using Average() : 59.2

В примере выше используется:

  • numbers.Sum() – для получения суммы элементов.
  • numbers.Count() – для получения количества элементов, находящихся внутри массива.

Затем сумма элементов делится на количество элементов в массиве, чтобы получить среднее значение.

        float average = sum / count;
    

Также используется numbers.Average() пространства имен System.Linq, чтобы напрямую получить среднее значение.

Примечание
Используйте пространство имен System.Linq при использовании методов Min(), Max(), Sum(), Count() и Average().

Многомерные массивы

В этом руководстве рассматриваются многомерные массивы в C# на примере двумерного массива.

В многомерных массивах каждый элемент массива также массив.

Пример:

        int[ , ] x = { { 1, 2 ,3}, { 3, 4, 5 } };
    

x – многомерный массив, у которого два элемента: { 1, 2, 3 } и { 3, 4, 5 }. И каждый элемент массива содержит три элемента.

Двумерный массив

Двумерный массив (2D-массив) состоит из одномерных массивов в качестве элементов. Представим это в виде таблицы с заданным количеством строк и столбцов.

Двумерный массив C#
Двумерный массив C#

Строки { 1, 2, 3 } и { 4, 5, 6 } – это элементы 2D-массива.

Объявление двумерного массива

Вот как объявляется двумерный массив в C#:

        int[ , ] x = new int [2, 3];
    

x – двумерный массив из двух элементов. И каждый элемент – это также массив из трех элементов. Значит массив хранит шесть элементов.

Примечание
Примечание: Одиночная запятая [ , ] представляет собой двумерный массив.

Инициализация двумерного массива

В C# допустимо инициализировать массив в момент объявления.

Пример:

        int[ , ] x = { { 1, 2 ,3}, { 3, 4, 5 } };
    

x – 2D-массив с двумя элементами { 1, 2 ,3 } и { 3, 4, 5 }. Видно, что каждый элемент массива также массив.

Также допустимо указать количество строк и столбцов в момент инициализации.

Пример:

        int [ , ] x = new int[2, 3]{ {1, 2, 3}, {3, 4, 5} };
    

Доступ к элементам 2D-массива

Порядковый номер используется для доступа к элементам двумерного массива.

Пример:

        // 2D массив
int[ , ] x = { { 1, 2 ,3}, { 3, 4, 5 } };

// доступ к первому элементу, первой строки
x[0, 0];  // вернётся 1

// доступ к третьему элементу второй строки
x[1, 2];  // вернётся 5

// доступ к третьему элементу первой строки
x[0, 2];  // вернётся 3
    
Элементы двумерного массива в C#
Элементы двумерного массива в C#
Двумерный массив C#
        using System;

namespace MultiDArray {
  class Program {
    static void Main(string[] args) {
           
        // инициализация 2D массива
       int[ , ] numbers = {{2, 3}, {4, 5}};
 	 
        // получение доступа к первому элементу первой строки
       Console.WriteLine("Element at index [0, 0] : "+numbers[0, 0]);
  	 
        // получение доступа к первому элементу второй строки
       Console.WriteLine("Element at index [1, 0] : "+numbers[1, 0]);
    }
  }
}

    

Вывод:

Element at index [0, 0] : 2
Element at index [1, 0] : 4

В примере выше создается массив с именем numbers со строками { 2, 3 } и { 4, 5 }.

Для доступа к элементам двумерного массива используется номер индекса.

  • numbers[0, 0] – доступ к первому элементу первой строки (2).
  • numbers[1, 0] – доступ к первому элементу второй строки (4).

Изменение элементов 2D-массива

Также можно изменять элементы двумерного массива. Для изменения элемента присваивается новое значение конкретному индексу.

Пример:

        using System;

namespace MultiDArray {
  class Program {
    static void Main(string[] args) {

    int[ , ] numbers = {{2, 3}, {4, 5}};
 	 
     // старый элемента
    Console.WriteLine("Old element at index [0, 0] : "+numbers[0, 0]);
 	 
      // присваивание нового значения
    numbers[0, 0] = 222;
  	 
      // новый элемент
    Console.WriteLine("New element at index [0, 0] : "+numbers[0, 0]);
    }
  }
}

    

Вывод:

Old element at index [0, 0] : 2
New element at index [0, 0] : 222

В примере выше, начальное значение по индексу [0, 0] равно 2. Обратите внимание на строку:

        // присваивание нового значения
    numbers[0, 0] = 222;

    

Присваиваем новое значение 222 по индексу [0, 0]. Теперь значение по индексу [0, 0] изменилось с 2 на 222.

Обход массива с помощью цикла

        using System;

namespace MultiDArray {
  class Program  {
    static void Main(string[] args)  {

      int[ , ] numbers = { {2, 3, 9}, {4, 5, 9} };
   	 
      for(int i = 0; i < numbers.GetLength(0); i++)  { 
        Console.Write("Row "+ i+": ");

        for(int j = 0; j < numbers.GetLength(1); j++)  { 
          Console.Write(numbers[i, j]+" ");
 
        }
        Console.WriteLine(); 
  
      }  
    }
  }
}

    

Вывод:

Row 0: 2 3 9
Row 1: 4 5 9

В примере выше используется вложенный цикл for для обхода элементов двумерного массива.

  • numbers.GetLength(0) – получение количества строк в 2D-массиве
  • numbers.GetLength(1) – получение количества элементов в строке
Примечание
Также допустимо создать трехмерный (3D) массив. Технически 3D массив – это массив, состоящий из нескольких двумерных массивов в качестве элементов.

Пример:

        int[ , , ] numbers = { { { 1, 3, 5 }, { 2, 4, 6 } },
                                 { { 2, 4, 9 }, { 5, 7, 11 } } };

    

Здесь:

[ , , ] (2 запятые) обозначает 3D-массив.

Ступенчатые (зубчатые) массивы

Рассмотрим объявления, инициализацию и доступ к ступенчатым массивам.

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

Объявление ступенчатого массива

Вот синтаксис для объявления ступенчатого массива в C#:

dataType[ ][ ] nameOfArray = new dataType[rows][ ];

Давайте посмотрим на пример:

        // объявляем ступенчатый массив
int[ ][ ] jaggedArray = new int[2][ ];

    
  • int – тип данных массива.
  • [][] – представляет ступенчатый массив.
  • jaggedArray – имя массива.
  • [2][] – указывает количество элементов в ступенчатом массиве.

Поскольку известно, что каждый элемент ступенчатого массива – это тоже массив, можно установить размер отдельного массива.

Пример:

        // зададим размер первого массива равный 3
jaggedArray[0] = new int[3];

// зададим размер второго массива равный 2
jaggedArray[1] = new int[2];

    

Инициализация ступенчатого массива

Существуют разные способы инициализации ступенчатого массива.

1. С помощью индекса

Как только объявляется массив, для инициализации используется индекс.

Пример:

        // инициализируем первый массив
jaggedArray[0][0] = 1;
jaggedArray[0][1] = 3;
jaggedArray[0][2] = 5;

// инициализируем второй массив
jaggedArray[1][0] = 2;
jaggedArray[1][1] = 4;

    
  • Индекс внутри первой квадратной скобки представляет собой индекс зубчатого массива.
  • Индекс внутри второй квадратной скобки представляет собой индекс внутри каждого элемента зубчатого массива.

2. Инициализация массива без установки размера элементов массива

        // объявление ступенчатого массива
int[ ][ ] jaggedArray = new int[2] [ ];

// инициализация каждого массива
jaggedArray[0] = new int[] {1, 3, 5};
jaggedArray[1] = new int[] {2, 4};

    

3. Инициализация при объявлении ступенчатого массива

        int[ ][ ] jaggedArray = {
    new int[ ] {10, 20, 30},
    new int[ ] {11, 22},
    new int[ ] {88, 99}
};

    

Доступ к элементам зубчатого массива

Доступ к элементам зубчатого массива получается с помощью номера индекса.

Например:

        // доступ к первому элементу второго массива
jaggedArray[1][0];

// доступ ко второму элементу второго массива
jaggedArray[1][1];

// доступ ко второму элементу первого массива
jaggedArray[0][1];
    
C# Ступенчатый массив
        using System;

namespace JaggedArray {
  class Program {
    static void Main(string[] args) {

     // создание ступенчатого массива
     int[ ][ ] jaggedArray = {
         new int[] {1, 3, 5},
         new int[] {2, 4},
      };

     // вывод элементов ступенчатого массива
     Console.WriteLine("jaggedArray[1][0]: " + jaggedArray[1][0]);
     Console.WriteLine("jaggedArray[1][1]: " + jaggedArray[1][1]);

     Console.WriteLine("jaggedArray[0][2]: " + jaggedArray[0][2]);

     Console.ReadLine();
    }    
  }
}
    

Вывод:

jaggedArray[1][0]: 2
jaggedArray[1][1]: 4
jaggedArray[0][2]: 5

Внутри зубчатого массива:

  • jaggedArray[1][0] – первый элемент второго массива.
  • jaggedArray[1][1] – второй элемент второго массива.
  • jaggedArray[0][2] – третий элемент первого массива.

Обход зубчатого массива

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

Например:

        using System;
	
namespace JaggedArray {
  class Program {
    static void Main(string[] args) {

      // объявляем ступенчатый массив
      int[][] jaggedArray = new int[2][];

      // устанавливает размер элементов ступенчатого массива
      jaggedArray[0] = new int[3];
      jaggedArray[1] = new int[2];

      // инициализируем первый массив
      jaggedArray[0][0] = 1;
      jaggedArray[0][1] = 3;
      jaggedArray[0][2] = 5;

      // инициализируем второй массив
      jaggedArray[1][0] = 2;
      jaggedArray[1][1] = 2;
      	 
      // внешний цикл for
      for (int i = 0; i < jaggedArray.Length; i++) {

        Console.Write("Element "+ i +": ");
        // внутренний цикл for
        for (int j = 0; j < jaggedArray[i].Length; j++) {
          Console.Write(jaggedArray[i][j] + " ");
         }
      Console.WriteLine();
      }
      Console.ReadLine();
    } 
  }
}

    

Вывод:

Element 0: 1 3 5
Element 1: 2 2

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

1. Внешний цикл for:

  • Доступ к элементам (массивам) зубчатого массива.
  • jaggedArray.Length – возвращает размер i-го элемента внутри зубчатого массива.

2. Внутренний цикл for:

  • Доступ к элементам конкретного массива внутри зубчатого массива.
  • jaggedArray[i].Length – возвращает размер i-го массива внутри зубчатого массива.

Ступенчатый и многомерный массив

В C# многомерный массив также используется, как элемент ступенчатого массива.

Например:

        int[ ][ , ] jaggedArrayTwoD = new int[2][ , ] {
    	new int[,] { {1, 8}, {6, 7} },
    	new int[,] { {0, 3}, {5, 6}, {9, 10} }
};
    

Каждый элемент ступенчатого массива – многомерный массив:

  • new int[,] { {1, 8}, {6, 7} } – 2D-массив с двумя элементами.
  • new int[,] { {0, 3}, {5, 6}, {9, 10} } – 2D-массив с тремя элементами.

Давайте рассмотрим следующий пример:

        using System;

namespace JaggedArray  {
  class Program {
    static void Main(string[] args)  {
  	 
      // объявляем и инициализируем ступенчатый массив с 2D массивами
      int[][,] jaggedArray = new int[3][ , ]  {
          new int[ , ] { {1, 8}, {6, 7} },
          new int[ , ] { {0, 3}, {5, 6}, {9, 10} },
          new int[ , ] { {11, 23}, {100, 88}, {0, 10} }
      };

      Console.WriteLine(jaggedArray[0][0, 1]);
      Console.WriteLine(jaggedArray[1][2, 1]);
      Console.WriteLine(jaggedArray[2][1, 0]);

      Console.ReadLine();
    }    
  }
}
    

Вывод:

8
10
100

В примере выше обратите внимание на код:

        jaggedArray[0][0, 1]

    
  • [0] – это первый элемент (2D-массив) зубчатого массива
  • [0, 1] – это второй элемент первого массива внутри 2D-массива

Цикл foreach

C# предоставляет простую и более удобочитаемую альтернативу циклу for при переборе элементов массивов и коллекций – цикл foreach. Цикл foreach перебирает каждый элемент, поэтому он называется циклом foreach – для каждого.

Синтаксис цикла foreach

        foreach (element in iterable-item)
{
    // тело цикла foreach
}

    

iterable-item – может быть массивом или коллекцией.

Как работает цикл foreach?

Работа цикла C# foreach
Работа цикла C# foreach

Ключевое слово in используется вместе с циклом foreach для перебора элементов iterable-item. in выбирает элемент из iterable-item на каждой итерации и сохраняет в переменной element.

На первой итерации первый элемент iterable-item сохраняется в element. На второй итерации второй элемент сохраняется в element и т. д.

Число выполнений цикла foreach равно количеству элементов в массиве или коллекции.

Вот пример перебора массива с помощью цикла for:

Вывод массива используя цикл for
        using System;
 
namespace Loop
{
    class ForLoop
    {
        public static void Main(string[] args)
        {
            char[] myArray = {'H','e','l','l','o'};
 
            for(int i = 0; i < myArray.Length; i++)
            {
                Console.WriteLine(myArray[i]);
            }
        }
    }
}

    

Эта же задача решается с помощью цикла foreach.

Вывод массива используя цикл foreach
        using System;
 
namespace Loop
{
    class ForEachLoop
    {
        public static void Main(string[] args)
        {
            char[] myArray = {'H','e','l','l','o'};
 
            foreach(char ch in myArray)
            {
                Console.WriteLine(ch);
            }
        }
    }
}

    

После запуска обеих программ вывод будет таким:

H
e
l
l
o

В приведенной выше программе цикл foreach перебирает массив myArray. На первой итерации первый элемент, т. е. myArray[0] выбирается и сохраняется в ch.

Аналогично, на последней итерации выбирается последний элемент, т. е. myArray[4]. Внутри тела цикла выводится значение ch.

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

Следующая программа подсчитывает количество кандидатов мужского и женского пола.

Обход массива полов с использованием цикла foreach
        using System;
 
namespace Loop
{
    class ForEachLoop
    {
        public static void Main(string[] args)
        {
            char[] gender = {'m','f','m','m','m','f','f','m','m','f'};
            int male = 0, female = 0;
            foreach (char g in gender)  
            {
                if (g == 'm')
                        male++;
                else if (g =='f')
                        female++;
            }
            Console.WriteLine("Number of male = {0}", male);
            Console.WriteLine("Number of female = {0}", female);
        }
    }
}

    

Вывод:

Number of male = 6
Number of female = 4

Следующая программа подсчитывает сумму элементов в List.

Цикл foreach с List (список или коллекция)
        using System;
using System.Collections.Generic;
namespace Loop {
  class ForEachLoop {
    public static void Main(string[] args) {
      var numbers = new List<int>() { 5, -8, 3, 14, 9, 17, 0, 4 };
      int sum = 0;
      foreach (int number in numbers) {
        sum += number;
      }
      Console.WriteLine("Sum = {0}", sum);
      Console.ReadLine();
    }
  }
}

    

Вывод:

Sum = 44

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

Первый элемент коллекции выбирается на первой итерации, второй элемент на второй и т. д. до последнего элемента.

***

Из этой статьи мы узнали

  • Как работать с одномерными, многомерными и ступенчатыми массивами.
  • Как работать с циклом foreach.
  • О пространстве имен System.Linq и несколько примеров работы с ним.

Материалы по теме

Источники

Комментарии

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ