• Массив х объявлен с явной инициализацией. Число и значения его элементов определяется константным массивом.
• Массивы u и v объявлены с отложенной инициализацией. В последующих операторах массив и инициализируется в объектном стиле — элементы получают его в цикле значения.
• Обратите внимание на закомментированный оператор присваивания. В отличие от инициализации, использовать константный массив в правой части оператора присваивания недопустимо. Эта попытка приводит к ошибке, поскольку v — это ссылка, которой можно присвоить ссылку, но нельзя присвоить константный массив. Ссылку присвоить можно. Что происходит в операторе присваивания v = u? Это корректное ссылочное присваивание: хотя u и v имеют разное число элементов, но они являются объектами одного класса. В результате присваивания память, отведенная массиву v, освободится, ею займется теперь сборщик мусора. Обе ссылки u и v будут теперь указывать на один и тот же массив, так что изменение элемента одного массива немедленно отразится на другом массиве.
• Далее определяется двумерный массив w и делается попытка выполнить оператор присваивания v=w. Это ссылочное присваивание некорректно, поскольку объекты w и v — разных классов и для них не выполняется требуемое для присваивания согласование по типу.
• Для поддержки работы с массивами создан специальный класс Arrs, статические методы которого выполняют различные операции над массивами. В частности, в примере использованы два метода этого класса, один из которых заполняет массив случайными числами, второй — выводит массив на печать. Вот текст первого из этих методов:
public static void CreateOneDimAr (int [] A)
{
for(int i = 0; i<A.GetLength(0);i++)
A[i] = rnd.Next(1,100);
}//CreateOneDimAr
Здесь rnd — это статическое поле класса Arrs, объявленное следующим образом:
private static Random rnd = new Random();
Процедура печати массива с именем name выглядит так:
public static void PrintArl(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();
}//PrintArl
На рис. 11.1 показан консольный вывод результатов работы процедуры TestDeciarations.
Рис. 11.1. Результаты объявления и создания массивов
Особое внимание обратите на вывод, связанный с массивами u и v.
Динамические массивы
Во всех вышеприведенных примерах объявлялись статические массивы, поскольку нижняя граница равна нулю по определению, а верхняя всегда задавалась в этих примерах константой. Напомню, что в C# все массивы, независимо оттого, каким выражением описывается граница, рассматриваются как динамические, и память для них распределяется в "куче". Полагаю, что это отражение разумной точки зрения: ведь статические массивы, скорее исключение, а правилом является использование динамических массивов. В действительности реальные потребности в размере массива, скорее всего, выясняются в процессе работы в диалоге с пользователем.
Чисто синтаксически нет существенной разницы в объявлении статических и динамических массивов. Выражение, задающее границу изменения индексов, в динамическом случае содержит переменные. Единственное требование — значения переменных должны быть определены в момент объявления. Это ограничение в C# выполняется автоматически, поскольку хорошо известно, сколь требовательно C# контролирует инициализацию переменных.
Приведу пример, в котором описана работа с динамическим массивом-.
public void TestDynAr()
{
//объявление динамического массива А1
Console.WriteLine("Введите число элементов массива А1");
int size = int.Parse(Console.ReadLine());
int[] A1 = new int[size];
Arrs.CreateOneDimAr(A1);
Arrs.PrintAr1("A1",A1);
}//TestDynAr
В особых комментариях эта процедура не нуждается. Здесь верхняя граница массива определяется пользователем.