Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSBasicCourse2ndedPodbelsky / CSBasicCourse2ndedPodbelsky.rtf
Скачиваний:
27
Добавлен:
22.03.2016
Размер:
11.9 Mб
Скачать

7.5. Массивы массивов и поверхностное копирование

Итак, массив массивов

"массив:массив массивов"

представляет собой

одномерный

массив,

элементами

которого

являются

ссылки

на

массивы

следующего (подчинённого) уровня. Этот факт требует особого внимания, так как

затрагивает фундаментальные вопросы копирования ссылок "ссылка:копирование

ссылок" и тех объектов, которые ими адресуются.

Независимо от того, какого вида массив мы рассматриваем, присваивание

ссылке на массив значения другой ссылки на уже существующий массив (на объект

с типом массива) приводит к появлению двух ссылок на один массив. Это мы уже

иллюстрировали и разобрали.

Метод Clone() позволяет создать новый экземпляр массива. В программе

07_04.cs показано, что изменяя один из одномерных массивов-копий, мы не

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

многомерному массиву:

// 07_08.cs - двумерный массив - полное клонирование

using System;

class Program

{

static void Main( )

{

Int size;

do Console.Write("size = ");

while (!int.TryParse(Console.ReadLine(), out size)||size<1);

int[,] one = new int[size, size];

Console.WriteLine("Массив one:");

for (int i = 0; i < size; i++, Console.WriteLine())

for (int j = 0; j < size; j++)

{

if (i == j) one[i, j] = 1

;

Console.Write(one[i, j] + "\t");

}

Console.WriteLine("one.Length = " + one.Length);

int[,] two = (int[,])one.Clone(); // клонирование

two[0, 0] = -size;

Console.WriteLine("Массив two:");

for (int i = 0; i < size; i++, Console.WriteLine())

for (int j = 0; j < size; j++)

Console.Write(two[i, j] + "\t");

Console.WriteLine("Массив one:");

for (int i = 0; i < size; i++, Console.WriteLine())

for (int j = 0; j < size; j++)

Console.Write(one[i, j] + "\t");

}

}

Результат выполнения программы:

size = 4<ENTER>

Массив one:

1 0 0 0

0 1 0 0

0 0 1 0

0 0 0 1

one.Length = 16

Массив two:

-4 0 0 0

0 1 0 0

0 0 1 0

0 0 0 1

Массив one:

1 0 0 0

0 1 0 0

0 0 1 0

0 0 0 1

В программе определена ссылка two типа int[,], и ей присвоен результат

копирования массива, связанного со ссылкой one, имеющей тот же тип int[,].

Выведена единичная матрица, адресованная ссылкой one, затем изменён обычным

присваиванием один элемент массива–копии:

two[0,0]=-size;

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

независимость массива-оригинала от массива-копии.

Программы 07_04.cs и 07_08.cs работают с массивами, у которых по одному

спецификатору размерности. В первом случае массив одномерный, во второй

программе клонируется двумерный массив. Применяя метод Clone() к массиву

массивов, мы сталкиваемся с очень важной особенностью. Строго говоря, действия

метода остаются прежними – он создаёт массив-копию и присваивает его элементам

значения элементов массива-оригинала. Однако, в этом случае копирования тех

подчинённых массивов, на которые "смотрят" ссылки-элементы массива-оригинала,

не

происходит

.

Выполняется

,

так

называемое

,

поверхностное

"копирование:поверхностное копирование"

или поразрядное копирование

"копирование:поразрядное копирование" . Иначе и быть не должно – "не знает"

метод Clone(), что код, который является значением элемента массива, представляет

собой ссылку, и по этой ссылке нужно ещё что-то "доставать".

Таким образом, копируя с помощью метода Clone() массив массивов, мы

получаем два экземпляра массива верхнего уровня, элементы которых адресуют

одни и те же участки памяти, выделенные для подчинённых массивов объекта-

оригинала.

В

качестве

иллюстрации

указанной

ситуации

приведём

следующую

программу, построенную на основе 07_06.cs:

/ 07_09.cs - непрямоугольный массив –

// клонирование поверхностное!

using System;

class Program

{

static void Main( )

{

Соседние файлы в папке CSBasicCourse2ndedPodbelsky