Читать в оригинале

<< Предыдущая Оглавление Следующая >>


7.1. Одномерные массивы

Забудем пока об атрибутах и модификаторах. Объявление одномерного массива выглядит следующим образом:

<тип>[ ] <объявители>;

Отметим, что в отличие от языка C++ квадратные скобки приписаны не к имени переменной, а к типу. Они являются неотъемлемой частью определения класса, так что запись T[ ] следует понимать как класс «одномерный массив» с элементами типа T.

Что же касается границ изменения индексов, то эта характеристика к классу не относится, она является характеристикой переменных - экземпляров, каждый из которых является одномерным массивом со своим числом элементов, задаваемых в объявителе переменной.

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

int[ ] a, b, c;

Чаще всего при объявлении массива используется имя с инициализацией. И опять-таки, как и в случае простых переменных, могут быть два варианта инициализации. В первом случае инициализация является явной и задается константным массивом. Вот пример:

double[ ] x = {5.5, 6.6, 7.7};

Следуя синтаксису, элементы константного массива следует заключать в фигурные скобки.

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

int[ ] d = new int[5];

В этом случае инициализация выполняется конструктором, а в динамической памяти создается сам массив, элементы которого инициализируются константами соответствующего типа (ноль для арифметики, пустая строка для строковых массивов), и ссылка связывается с этим массивом. Если массив инициализируется константным массивом, то в памяти создается константный массив, с которым и связывается ссылка.

Давайте рассмотрим первый пример работы с массивами из проекта с именем Arrays:

public void TestDeclaration() {
          //объявляются три одномерных массива A,B,C
          int[ ] A = new int[5], B = new int[5], C = new int[5];
          //объект специального класса для выполнения операций с массивами Arrs1
          Arrs = new Arrs1();
          Arrs.CreateOneDimAr(A);
          Arrs.CreateOneDimAr(B);
          for (int i = 0; i < 5; i++)
            C[i] = A[i] + B[i];
          //объявление массива с явной инициализацией
          int[ ] x = {5, 5, 6, 6, 7, 7};
          //объявление массивов с отложенной инициализацией
          int[ ] u, v;
          u = new int[3];
          for (int i = 0; i < 3; i++)
            u[i] = i + 1;
          //v= {1,2,3};      //присваивание константного массива недопустимо
          v = new int[4];
          v = u; //допустимое присваивание
          Arrs.PrintAr1("A", A);
          Arrs.PrintAr1("B", B);
          Arrs.PrintAr1("C", C);
          Arrs.PrintAr1("X", x);
          Arrs.PrintAr1("U", u);
          Arrs.PrintAr1("V", v);
}

На что следует обратить внимание, анализируя этот текст:

В процедуре показаны разные способы объявления массивов. Вначале объявляются одномерные массивы A, B и C, создаваемые конструктором. Значения элементов этих трех массивов имеют один и тот же тип int. Отметим, что после такого объявления с инициализацией конструктором, все элементы имеют значение, в данном случае - ноль, и могут участвовать в вычислениях.

Массив x объявлен с явной инициализацией. Число и значения его элементов определяется константным массивом.

Массивы u и v объявлены с отложенной инициализацией. В последующих операторах массив u инициализируется в объектном стиле - его элементы получают в цикле значения.

Обратим внимание на закомментированный оператор присваивания. В отличие от инициализации, использовать константный массив в правой части оператора присваивания недопустимо. Эта попытка приводит к ошибке, поскольку v - это ссылка, которой можно присвоить ссылку, но нельзя присвоить константный массив. Что происходит в операторе присваивания v = u? Это корректное ссылочное присваивание: хотя u и v имеют разное число элементов, но они являются объектами одного класса. В результате присваивания память, отведенная массиву v, освободится, ею займется теперь сборщик мусора. Обе ссылки u и v будут теперь указывать на один и тот же массив, так что изменение элемента одного массива немедленно отразится на другом массиве.

Далее определяется двумерный массив w и делается попытка выполнить оператор присваивания v = w. Это ссылочное присваивание некорректно, поскольку объекты w и v - разных классов и для них не выполняется требуемое для присваивания согласование по типу.

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

public void CreateOneDimAr(int[ ] A) {
          for (int i = 0; i < A.GetLength(0); i++)
            A[i] = rnd.Next(1, 100);
} //CreateOneDimAr

Здесь rnd - это статическое поле класса Arrs, объявленное следующим образом:

private Random rnd = new Random();
Процедура печати массива с именем name выглядит так:
public void PrintAr1(string name, int[] A) {
          Console.WriteLine(name);
          for (int i = 0; i < A.GetLength(0); i++)
            Console.Write("\t" + name + "[{0}]={1}", i, A[i]);
          Console.WriteLine();
} //PrintAr1

На рис. 23 показан консольный вывод результатов работы процедуры TestDeclarations.

Рисунок 23. Результаты объявления и создания массивов

Особое внимание обратите на вывод, связанный с массивами u и v.

 



<< Предыдущая Оглавление Следующая >>