Лабораторная работа №5. Массивы

Массивом называют упорядоченную совокупность элементов од­ного типа. Число индексов характеризует размерность массива. При объявлении массива границы задаются выражениями. Если все грани­цы заданы константами, то такие массивы называются статическими. Если же выражения, задающие границы, зависят от переменных, то такие массивы называются динамическими, память им отводится в процессе выполнения программы.

В языке C# имеются одномерные массивы, массивы массивов и многомерные ступенчатые массивы.

Определение одномерных массивов:

int[] k; //k - одномерный массив

k=new int [3]; //Определяем массив из трех целых

k[0]=-5; k[1]=4; k[2]=55; //Задаем элементы массива

Элементы массива можно задавать сразу при объявлении: int[] k = {-5, 4, 55};

Создание динамического массива: Console.WriteLine("Введите число элементов массива "); int size = Int32.Parse(Console.ReadLine()); int[] A1 = new int[size]; //создание динамического массива

Определение многомерных массивов:

int[,] k - new int [2,3];

Обратите внимение, что пара квадратных скобок только одна. Аналогично можно задавать многомерные массивы. Вот пример трехмерного массива:

int[,,] k = new int [10,10,10];

Многомерные массивы можно сразу инициализировать: int[,] k = {{2,-2},{3,-22},{0,4}};

Определение ступенчатых массивов:

int[][] k = new int [2][]; //Объявляем второй ступенчатый массив
k[0]-new int[3]; //Определяем нулевой элемент
k[1]-new int[4]; //Определяем первый элемент
k[1][3]-22; //записываем 22 в последний элемент


Обратите внимание, что у ступенчатых массивов задается несколь­ко пар квадратных скобок (столько, сколько размерностей у массива), табл. 5.1.

Массив имеет два уровня. Можно считать, что у него три элемента, каждый из которых является массивом. Для каждого внутреннего мас­сива необходимо вызвать конструктор new.

Базовый класс System.Array

Все классы-массивы являются потомками класса Array из библио­теки FCL. Класс имеет большое число методов и свойств (табл. 5.2, 5,3). Благодаря такому родителю над массивами определены самые разнообразные операции - копирование, поиск, обращение, сортиров­ка, получение различных характеристик. Массивы можно рассматри­вать как коллекции и устраивать циклы foreach для перебора всех эле­ментов.


Т аб ли ца 5.2

Т аб ли ца 5.3

Статические методы класса Array

Метод Описание
BinarySearch() Двоичный поиск
Clear() Выполняет начальную инициализацию элементов в зависимости от типа: 0 - для арифметического типа, false - для логического типа, null - для ссы­лок, "" - для строк
CopyTo() Копирование части или всего массива в другой массив. Описание и примеры даны в тексте
GetLength() Используется для определения количества эле­ментов в указанном измерении массива
IndexOf() Индекс первого вхождения образца в массив. Описание и примеры даны в тексте
LastIndexOf() Индекс последнего вхождения образца в массив. Описание и примеры даны в тексте
Reverse() Обращение одномерного массива


Программа 1. Применение методов класса Array public static int Main(string[] args) {

string[]firstNames={мСашам, "Маша", "Олег", "Света", "Игорь"}; Console.WriteLine("Here is the array:"); for(int i=0; i< firstNames.Length;

Console.WriteLine(firstNames[i]+"\t"); Console.WriteLine("\n"); Array.Reverse(firstNames); for(int i=0; i< firstNames.Length;

Console.WriteLine(firstNames[i]+"\t");

Console.WriteLine("\n");

Console.WriteLine("Cleared out all but one...");

Array.Clear(firstNames,1,4);

for(int i=0; i< firstNames.Length; i++)

Console.WriteLine(firstNames[i]+"\t\n"); return 0;

}

В процедуре PrintAr формальный аргумент класса Array, следова­тельно, можно передавать массив любого класса в качестве фактиче­ского аргумента

Программа 2. Примение методов класса Array public static void PrintAr(string name, Array A) { Console.WriteLine(name); switch (A.Rank) {

case 1:

for(int i = 0; i<A.GetLength(0);i++)

Console.Write("\t" + name + "[{0}]={1}", i, A.GetValue(i)); Console.WriteLine(); break;

case 2:

for(int i = 0; i<A.GetLength(0);i++) { for(int j = 0; j<A.GetLength(1);j++) Console.Write("\t" + name + "[{0},{1}]={2}", A.GetValue(i,j));

Console.WriteLine();

}

break; default: break;

}

}

Последовательность элементов – a1, a2, …. an – одна из любимых структур в математике. Последовательность можно рассматривать как функцию a(i), которая по заданному значению индекса элемента возвращает его значение. Эта функция задает отображение integer -> T, где T – это тип элементов последовательности.

В программировании последовательности называются массивами, но от этого они не перестают быть менее любимыми. Массив – это упорядоченная последовательность элементов одного типа. Порядок элементов задается с помощью индексов.

Для программистов важно то, как массивы хранятся в памяти. Массивы занимают непрерывную область памяти, поэтому, зная адрес начального элемента массива, зная, сколько байтов памяти требуется для хранения одного элемента, и, зная индекс (индексы) некоторого элемента, нетрудно вычислить его адрес, а значит и хранимое по этому адресу значение элемента. На этом основана адресная арифметика в языках C, C++, где адрес элемента a(i) задается адресным выражением a+i, в котором имя массива a воспринимается как адрес первого элемента. При вычислении адреса i-го элемента индекс i умножается на длину слова, требуемого для хранения элементов типа T. Адресная арифметика приводит к 0-базируемости элементов массива, когда индекс первого элемента равен нулю, поскольку первому элементу соответствует адресное выражение а+0.

Язык C# сохранил 0-базируемость массивов. Индексы элементов массива в языке C# изменяются в плотном интервале значений от нижней границы, всегда равной 0, до верхней границы, заданной динамически вычисляемым выражением, возможно зависящим от переменных. Массивы C# являются 0-базируемыми динамическими массивами. Это важно понимать с самого начала.

Не менее важно понимать и то, что массивы C# относятся к ссылочным типам. Рассмотрим следующий фрагмент программного кода:

int[] x, y = {1, 2, 3};

double[] z;

int[,] u, v = {{1,3,5},{2,4,6}};

Здесь объявлены пять переменных – x, y, z, u, v. Все они являются массивами, но разных типов. Переменные x и y принадлежат типу T = int[], задающему одномерные массивы с элементами целого типа int. Переменные u и v принадлежат другому типу T1 = int[,]- двумерных массивов с элементами целого типа. Переменная z принадлежит типу T3 –одномерных массивов с элементами вещественного типа double. Все три типа массивов – T1, T2, T3 являются наследниками общего родителя – типа (класса) Array, наследуя от родителя многие полезные свойства и методы. Все пять переменных являются типизированными ссылками. В момент объявления три переменные – x, z и u не инициализированы и потому являются «висячими» ссылками со значением null. Переменные y и v объявлены с инициализацией. При инициализации в динамической памяти создаются два объекта соответственно типов T1 и T3, фактически и задающие реальные массивы. У первого из этих объектов 3 элемента, у второго - 6. Ссылки y и v связываются с этими объектами. При связывании тип ссылки и тип объекта должны быть согласованными. Заметьте, число элементов в массиве является характеристикой объекта, а не типа. Ссылка может быть связана с объектами, содержащими различное число элементов, необходимо лишь выполнение условия согласования типов.

Дополним код следующими строчками:

x = new int[10];

z = new double[20];

u = new int[3, 5];

Здесь последовательно вызываются три конструктора типов T1, T2, T3, создающие новые три объекта в памяти и ссылки x, y, z связываются с этими объектами, так что у массива x теперь 10 элементов, z – 20, u -15.

Рассмотрим, что произойдет в результате присваивания:

x = y;

u = v;

Присваивание законно, поскольку переменные в левой и правой части имеют один и тот же (следовательно, согласованный) тип. В результате присваивания переменные порвут связь с теми объектами, с которыми они были связаны, и будут связаны с новыми объектами, так что x теперь имеет 3 элемента, u – 6.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: