Рубріки: ОсновыТеория

Массивы в C#: виды, примеры и работа с ними

Денис Бородовский

Массивы — основа любого языка программирования. Знать, как они работают, необходимо любому уважающему себя разработчику. Ну а если вы только начинаете свой путь программиста — сначала нужно разобраться с определением и назначением этой базовой структуры данных. Сейчас мы последовательно обсудим все основные реализации массивов в C#.

Массивы в C# и работа с ними

Массив — структура данных, содержащая ряд значений одинакового типа, расположенных последовательно, и обозначенная при помощи специального синтаксиса. Проще говоря, это набор однотипных значений хранящихся в последовательно расположенных ячейках памяти. Это полезная вещь избавила разработчиков от необходимости создавать тысячи переменных для каждого отдельно взятого значения. Вместо этого, с появлением такой структуры, мы просто делаем объявление переменной массива и добавляем туда поля одного типа данных, группируя их по определенному признаку. Уже оттуда можно получить доступ к конкретному элементу используя его порядковый номер (индекс).

Из основных преимущества массивов можно выделить: доступность значений хранящихся в различных ячейках памяти и более простое манипулирование данными (сортировка, перемещение и другие операции). Недостатки массива — ограничение его размера и условие однотипности (гомогенности) хранимых данных. Получить помощь при изучении этого языка программирования можно посетив курс наших друзей школы Hillel.

Далее поговорим о массивах на примере их реализации в языке C#.

Какие бывают массивы в языке C#

C# предоставляет нам на выбор 3 различных типа массивов:

  • Одномерный массив. Содержит только одну строку данных, поэтому к элементу, хранящемуся в массиве, довольно просто получить доступ с помощью одного числового индекса, ( 0, 1, 2 и т. д.)
  • Многомерный массив. Содержит более одной строки с данными, поэтому его индекс будет состоять из пары чисел, одно из которых идентифицирует строку, а другое — столбец. Такой массив часто называют прямоугольным, так как он принимает форму прямоугольника, если представить его схематично.
  • Зубчатый массив. Это массив, состоящий из подмассивов(причем эти подмассивы могут быть любого размера).

Объявляем и инициализируем массив в C#

Для объявления C#-массива используется эта нехитрая конструкция:

тип данных [] имя массива ;

Объявление C#-массива / Источник: coderlessons.com

Например :

int [] integerArray; // числовой массив 
string [] stringArray; // строковый массив
bool [] booleanArray; // логический массив

Как и во многих других языках программирования, в этом примере  массив объявлен, но не создан. Для того чтобы создать экземпляр массива используется ключевое слово new.

Например:

int32 [] values; // объявленный массив values пока не создан 
values = new int32[3]; // сейчас мы его создали, при этом определили, что он будет состоять из 3 целых чисел, но пока не заполнили значениями
values[0]=1; // значение первого элемента этого массива теперь равно единице. В квадратных скобках 0, ведь считать элементы в массиве надо начинать именно с него.

Следуюший шаг — инициализируем наш массив.

Инициализация — это процедура присваивания значений свободным ячейкам массива. Информация может присваиваться поэлементно, как в последнем действии предыдущего примера:

values[0]=1; 
values[1]=2; 
values[2]=3; 

Инициализация массива / Источник: coderlessons.com

Теперь попытаемся вывести в консоль значения элементов массива:

Значения элементов / Источник: coderlessons.com

Этот код распечатает следующие значения:

1
2
3

Но есть еще и другой способ инициализации. Вместо использования ключевого слова new, необходимые значения нашего массива можно перечислить в фигурных скобках. Например:

int32[] values = { 1, 2, 3};  

В этом случае компилятор сначало посчитает количество переменных, потом определит тип, выделит необходимое количество ячеек в области оперативной памяти и проинициализирует их необходимыми значениями. При объявлении массива через new, все элементы инициализируются автоматически:

  • нулями — для цельночислового типа;
  • false — для логического;
  • null — для ссылок.

Неявная типизация массива

Как и при работе с обыкновенными переменными, при объявлении массива существует возможность типизировать его неявно, поставив перед ним ключевое слово var. В такой ситуации компилятору C#  придется определять типы элементов по их инициализируемым значениям. Вот небольшой пример неявной типизации массива:

var capitals = new[] { “Moscow”, “Washington”, “Antananarivo” }; // Массиву будет автоматически присвоен строковый тип 
var integers= new[] { 3, 12, 43, 24, 7 }; // Массиву будет присвоен целочисленный тип
var mixer = new[] { 6, 24.3951d, false, “twelve”}; // А в этом случае, компилятор не определится с типом и выведет ошибку (т.к. в одном массиве присутствуют значения явно разных типов).

Определение массива объектов

Система типов используемая C# построена на системе наследования, в корне которой лежит класс System.Object, являющийся базой для всех типов данных. Такой подход помогает создавать массивы object, в ячейках которых можно хранить любые данные. Массив объектов как раз и используется для хранения разнотипных элементов. В C# ссылка на объект может указывать на любой экземпляр производного типа. Однако у такой структуры есть свои недостатки. Такая методика несколько усложняет код и увеличивает время выполнения программы.

Пример:

using System;
class GFG {
    static public void Main()
    {
        object[] arr = new object[6];// Создаем и инициализируем object array
        arr[0] = 1.859;
        arr[1] = 7;
        arr[2] = 'g';
        arr[3] = "hello";
        arr[4] = null;// это не отобразиться на выходе
        arr[5] = new object();// выведет System.Object
        foreach(var item in arr)
        {
            Console.WriteLine(item);// выводим элементы в консоль
        }
    }
}

Результат:

1,859
7
g
hello

System.Object

Длина массива

В С# существует параметр для измерения размера массива — это свойство Length. Оно возвращает нам количество, находящихся в массиве элементов, которое, после того как массив создан, изменить нельзя. Для доступа к этому параметру применяем следующий синтаксис:

arrayVariable.Length;

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

using System;
class MainClass{
   static void Main(){
      int[] myArr = new int[] { 1, 7, 6, 12, 18 };
      Console.WriteLine(myArr [myArr.Length-1]);
   }
}

Выведет: 18

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

Как мы уже упоминали ранее, для доступа к элементу массива нужно воспользоваться его порядковым номером (индексом). Например:

int[] digits = new int[4];
digits[0] = 1;
digits[1] = 3;
digits[2] = 4;
digits[3] = 5;
Console.WriteLine(digits[3]);  // 5

Не забываем, что нумерация элементов массива начинается с нуля, поэтому индекс 1-ого элемента будет 0, а четвертого — 3 ( digits[3]). Мы изначально задали, что наш массив состоит из 4 элементов, поэтому, если обратиться, например, к шестому элементу digits[5] = 5  — получим в результате исключение IndexOutOfRangeException.

Передача массива в метод

Стандартная форма, при которой одномерный массив передается в метод выглядит так:

public return_type MethodName(type[] parameterName)
{
  // ...
}

Здесь:

  • public – модификатор доступа;
  • return_type – тип, который вернул нам метод;
  • MethodName – имя метода;
  • type – тип массива, переданного в метод;
  • parameterName – название массива, являющегося одним из параметров нашего метода.

В следующем примере мы передаем массив в метод PrintArray.

int[] theArray = { 1, 3, 5, 7, 9 };
PrintArray(theArray);
Реализация метода печати.
void PrintArray(int[] arr)
{
    // какой-то код
}

Теперь все это можно соединить вместе, как показано в следующем примере:

PrintArray(new int[] { 1, 3, 5, 7, 9 });

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

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

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

Здесь i — это многомерный массив, состоящий из двух элементов: {1, 2, 3} и {3, 4, 5} . Каждый элемент такого массива является массивом размером в 3 элемента. Чаще всего C#-разработчики применяют в своей работе двумерные массивы, их мы и рассмотрим более подробно.

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

Двумерный массив / Источник: metanit.com

Подмассивы {1, 2, 3} и {3, 4, 5} являются элементами нашего двумерного массива.

Вот как он объявляется в C#:

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

Здесь i — это двумерный массив состоящий из  двух элементов, а каждый элемент представляет собой вложенный массив из 3 элементов. Если посчитать, всего в таком массиве можно хранить 6 элементов.

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

Также как и с одномерным массивом, в C# мы можем инициализировать двумерный массив во время объявления. Например:

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

Еще мы можем указать количество строк и столбцов во время инициализации. Например:

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

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

int[ , ] i = { { 1, 2 ,3}, { 3, 4, 5 } };
// доступ к первому элементу в строке
i[0, 0];  // вернет 1
// доступ ко второму элементу в строке
i[1, 2];  // вернет 5
// доступ к третьему элементу в строке
i[0, 2];  // вернет 3

Элементы двумерного массива в C# / Источник: metanit.com

Пример 2D-массива:

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

Выведет:

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

В приведенном выше примере мы создали 2D-массив с элементами {2, 3} и {4, 5} .

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

  • digits[0, 0] — доступ к первому элементу из первой строки ( 2 )
  • digits[1, 0] — доступ к первому элементу из второго ряда ( 4 )

Зубчатые массивы

Массив массивов (он же «зубчатый») отличается от многомерного тем, что в его состав могут входить подмассивы различной длины. Записывается он, при помощи двух пар квадратных скобок, при этом его длина обозначается только в в первой паре скобок. Например:

int[][] digits = new int[3][];
digits[0] = new int[2] { 1, 2 }; // выделяется место первому подмассиву
digits[1] = new int[3] { 1, 2, 3 }; // выделяется место второму подмассиву
digits[2] = new int[5] { 1, 2, 3, 4, 5 }; // выделяется место третьему подмассиву

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

В качестве подмассивов в нем можно использовать даже многомерные массивы:

int[][,] digits = new int[3][,]
{
    new int[,] { {1,2}, {3,4} },
    new int[,] { {1,2}, {3,6} },
    new int[,] { {1,2}, {3,5}, {8, 13} }
};

На следующей картинке изображены примеры существующих в C# массивов:

Примеры существующих в C# массивов / Источник: metanit.com

Перебор массивов (foreach)

При помощи цикла foreach мы можем перебирать элементы в любом контейнере, в том числе и в массиве. Синтаксис для его объявления такой:

foreach (data_type var_name in container)
{
    // какой то код
}

Простой пример:

int[] digits = new int[] { 1, 2, 3, 4, 5 };
foreach (int i in digits)
{
    Console.WriteLine(i);
}

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

Класс System.Array

Это абстрактный базовый класс (что означает, что вы не можете создать экземпляр этого класса) предоставляет нам методы и свойства для работы с массивами в C#. Разберем небольшой пример, где реализуем метод данного класса CreateInstance, создающий экземпляр массива. В нем, первым параметром будет тип, а вторым — измерение (т.е размерность массива: одномерный, двумерный и т.д.). А после создания нашего массива применим метод GetValue для добавления в него элементов.

Пример:

System.Array myArray;
myArray = System.Array.CreateInstance (GetType (string), 3);
myArray.SetValue ("one", 0);
myArray.SetValue ("two", 1);
myArray.SetValue («three», 2);
myArray = System.Array.CreateInstance (GetType (string), 3, «one», «two», «three»);
sValue = System.Convert.ToString (myArray.GetValue (2));

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

Резюмируем:

  1. Массивы нужны для структурирования и хранения информации
  2. Для объявления C#-массива необходимо указать его тип, квадратные скобки( знак массива) и как-то его назвать : тип данных [] имя массива.
  3. Инициализировать массив можно добавляя значение каждому элементу последовательно или перечислить значения в фигурных скобках, во время объявления, заставляя компилятор проставить необходимые сведения самому.
  4. В C# существует возможность реализовать массив объектов для хранения разнотипных элементов.
  5. Для определения длины массива используем свойство Length
  6. Многомерные массивы служат для хранения других массивов(в качестве элементов) с одинаковой длиной. Если длина хранящихся подмассивов неодинаковая — используем зубчатый массив.
  7. Для перебора массивов используем циклы for и foreach.
  8. Для удобства работы с рассматриваемыми структурами данных используем класс System.Array, изобилующий полезными методами и свойствами, необходимыми в повседневной работе С-программиста.

Тем кто хочет изучить язык более подробно, мы можем порекомендовать курс от друзей школы Hillel. Для тех людей, кому лучше изучать самостоятельно —  добавляем несколько ссылок на актуальные обучающие видеоролики от опытных C#-разработчиков:

Что такое массивы / Одномерный массив

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

Как работать с массивом на самом деле

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023