Шаг 56.
Язык программирования C#. Начала
Массивы. Двумерные массивы

    На этом шаге мы рассмотрим организацию и доступ к элементам такого массива.

    В двумерном массиве для однозначной идентификации элемента в массиве необходимо указать два индекса. Двумерный массив удобно представлять в виде таблицы. Первый индекс определяет строку, в которой находится элемент, а второй индекс определяет столбец. Создается двумерный массив практически так же, как и одномерный: объявляется переменная массива, создается собственно массив, и ссылка на этот массив записывается в переменную массива. При объявлении переменной двумерного массива после идентификатора типа указываются квадратные скобки с запятой внутри [,]. Например, если мы хотим объявить переменную для двумерного целочисленного массива, то соответствующая инструкция могла бы выглядеть как

  int[,] nums;     .

    При создании двумерного массива используется инструкция new, а после нее указывается идентификатор типа для элементов массива и в квадратных скобках разделенные через запятую два целых числа, определяющих размер массива по каждому из индексов (количество строк и столбцов в двумерном массиве). Например, создать двумерный целочисленный массив из 3 строк и 5 столбцов можно инструкцией

  new int [3, 5]. 

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

  int [,] nums;     , 
то законной была бы команда
  nums = new int [3, 5];       . 

    Команды объявления переменной массива и создания массива можно объединять:

  int[,] nums = new int [3, 5];           .

    Ниже приведен шаблон объявления переменной для двумерного массива и создания двумерного массива:

  тип[,] переменная;
  переменая = new тип[размер, размер];

    Можно использовать и такой шаблон:

  тип[,] переменная = new тип[размер, размер]; 

    Для обращения к элементу массива указывают имя массива и в квадратных скобках через запятую - индексы этого элемента. Индексация по каждому индексу начинается с нуля. То есть инструкция nums[0, 0] означает обращение к элементу массива nums, который расположен в первой строке и первом столбце (в строке с индексом 0 и столбце с индексом 0). Выражение nums[1, 2] является обращением к элементу, находящемуся в строке с индексом 1 (вторая по порядку строка) и столбце с индексом 2 (третий по порядку столбец).

    Свойство Length для двумерного массива возвращает общее количество элементов в массиве. То есть для массива nums из 3 строк и 5 столбцов значением выражения nums.Length является число 15 (произведение 3 на 5). Чтобы узнать размер массива по какому-то индексу (то есть количество строк или количество столбцов в массиве), используют метод GetLength(). Метод вызывается из переменной массива, а аргументом методу передается целое число, определяющее индекс, для которого возвращается размер массива.


Массивы в C# по факту реализуются как объекты. Как и у прочих объектов, у массива есть методы (и свойства). Более детально объекты обсуждаются немного позже. Здесь для нас важно научиться пользоваться преимуществами, которые имеются у массивов благодаря такому "объектному" способу их реализации.

    Размерность массива определяется количеством индексов, которые нужно указать для идентификации элемента массива. Определить размерность массива можно с помощью свойства Rank. Размерность двумерного массива равна 2.

    Если мы вызываем метод GetLength() с аргументом 0, то значением возвращается размер массива по первому индексу. Если вызвать метод GetLength() с аргументом 1, то получим размер массива по второму индексу.

    Например, если массив nums состоит из 3 строк и 5 столбцов, то значением выражения nums.GetLength(0) является число 3 (размер но первому индексу - количество строк), а значением выражения nums.GetLength(1) является число 5 (размер по второму индексу - количество столбцов).

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

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

namespace pr56_1
{
    class Program
    {
        static void Main()
        {
            // Количество строк и столбцов в массиве: 
            int rows = 3, cols = 5;
            // Создание двумерного массива: 
            int[,] nums = new int[rows, cols];
            // Значение первого элемента в массиве: 
            int value = 1;
            // Заполнение и отображение массива.
            // Перебор строк в массиве:
            for(int i = 0; i < nums.GetLength(0); i++) {
                // Перебор столбцов в строке: 
                for (int j = 0; j < nums.GetLength(1); j++) {
                    // Присваивание значения элементу массива: 
                    nums[i, j] = value;
                    // Это будет значение следующего элемента: 
                    value++;
                    // Отображение элемента в строке:
                    Console.Write(nums[i, j] + "\t");
                }
                // Переход к новой строке:
                Console.WriteLine();
            }
            // Задержка:
            Console.ReadLine();
        }
    }
}
Архив проекта можно взять здесь.

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


Рис.1. Результат работы приложения

    В программе количество строк и столбцов в двумерном массиве задается через целочисленные переменные rows и cols (значения 3 и 5 соответственно). Двумерный массив создается командой

  int[,] nums = new int[rows, cols];     .

    Для заполнения массива и отображения значений его элементов используются вложенные конструкции цикла. Во внешнем цикле индексная переменная i перебирает строки двумерного массива. Начальное значение переменной равно 0, а верхняя граница определяется значением выражения nums.GetLength(0) (количество строк в массиве nums - переменная i строго меньше этого значения). Во внутреннем цикле переменная j перебирает столбцы двумерного массива. Начальное значение переменной равно 0, и за каждый цикл переменная увеличивается на единицу. Конструкция цикла выполняется, пока значение переменной строго меньше значения выражения nums.GetLength(1) (количество столбцов в массиве nums). При заданных значениях индексов i и j командой

  nums[i, j] = value;
соответствующему элементу массива присваивается значение. Начальное значение переменной value равно 1, поэтому первый элемент в массиве (элемент с двумя нулевыми индексами - элемент в первой строке в первом столбце) получает единичное значение. После выполнения команды
  value++;
значение переменной value увеличивается на единицу. На следующей итерации цикла это новое значение будет присвоено очередному элементу.

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

  Console.Write(nums[i, j] + "\t");
оно отображается в консольном окне. Элементы из одной строки массива отображаются в одной и той же строке консольного окна. Для размещения элементов в строке использована табуляция.

    Тело внешнего цикла состоит из внутренней конструкции цикла и команды

  Console.WriteLine();                . 
Внутренний цикл нужен для заполнения строк массива и отображения значений элементов в консольном окне. Когда внутренний цикл завершает работу, благодаря команде
  Console.WriteLine();               
выполняется переход к новой строке. На этом завершается очередная итерация внешней конструкции цикла. На следующей итерации внешнего цикла снова выполняется внутренняя конструкция цикла, и затем команда
  Console.WriteLine();                ,
и так далее, пока не будут перебраны все строки двумерного массива.

    На следующем шаге мы закончим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг