Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Podbelsky_V_V_C_Bazovy_kurs.pdf
Скачиваний:
83
Добавлен:
02.06.2015
Размер:
1.73 Mб
Скачать

96

Г л а в а 6

 

 

21.Какие операторы могут прервать выполнение цикла до его завершения, запланированного выражением-условием?

22.Каково минимальное количество итераций в цикле с постусловием?

23.Назовите назначение оператора break. Где его можно применять?

24.Укажите возможности оператора goto при вложениях циклов.

25.Где и когда употребляется оператор continue?

26.Какого типа может быть значение переключающего выражения в переключателе?

27.Что называют меткой переключателя?

28.Каким оператором должна завершиться ветвь переключателя?

29.Какая конструкция вводит ветвь переключателя?

30.В каких случаях выполняется ветвь переключателя, введенная меткой default?

Массивы

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

Напомним, что система типов языка C# построена на основе классов. Типы делятся на четыре группы (значений, ссылок, указателей и тип void). С типами значений мы уже знакомы. К типам ссылок отнесены собственно классы (библиотечные и определяемые программистом), массивы и строки. Рассмотрим массивы.

Одномерный массив – набор однотипных элементов, доступ к которым осуществляется с помощью выражения с операцией индексирования:

имя_ссылки_на_массив [индексирующее_выражение]

Здесь имя_ссылки_на_массив – ссылка типа, производного от класса Array. Индексирующее_выражение должно иметь целочисленный тип (или приводится к целочисленному типу). Значение индексирующего выражения (иначе индекс) должно принадлежать фиксированному конечному диапазону [0, indMax], где 0

– нижняя граница, indMax – верхняя граница индекса. indMax однозначно определяет количество элементов (размер) массива, равное indMax+1.

Имя_ссылки_на_массив – выбираемый пользователем идентификатор. Чтобы идентификатор стал именем ссылки на массив, используется объявление вида:

тип [] имя_ссылки_на_массив;

Этим оператором объявляется переменная типа ссылки на массив, а тип определяет тип элементов этого массива. Кроме того, объявление указанного формата вводит в программу новый тип с обозначением тип[].

Примеры:

int [ ] integers; double [ ] points;

Здесь integers – ссылка на массив типа int [ ] с элементами типа int; points – ссылка на массив типа double [ ] с элементами типа double.

98

Г л а в а 7

 

 

В

результате обработки таких объявлений компиля-

тор выделит в стеке участки для размещения переменных (ссылок) integers и points. Однако, массивов, которые могут адресовать эти ссылки, пока не существует, и значениями integers и points является null. Каждый конкретный массив создается как объект класса, производного от класса Array, точнее от соответствующего ему системного класса System. Array.

Для создания экземпляра (объекта) конкретного типа массивов используется операция new. Выражение:

new тип [размер-массива]

определяет объект-массив с заданным в квадратных скобках количеством элементов указанного типа. Этот объект компилятор размещает в области памяти, называемой кучей (heap). Результат выполнения операции new – ссылка на выделенный для объекта участок памяти.

Чтобы связать ссылку с этим объектом, используют операцию присваивания:

имя_ссылки_на_массив= new тип[размер-массива];

Тип ссылки на массив должен соответствовать типу, указанному после операции new.

Примеры:

integers=new int [14]; points=new double [8];

После этих и предыдущих объявлений ссылка integers (размещенная в стеке) будет адресовать (ссылаться на) участок памяти в куче, отведенный для конкретного массива из 14 элементов типа int. Ссылка points будет связана с массивом из восьми элементов типа double.

Допустимо объединение объявления ссылки на массив и определения массива-объекта:

тип[ ] имя_ссылки_на_массив=new тип [размер_массива];

Пример:

char[ ] line = new char[12];

Массивы

99

 

 

Такое объявление вводит тип char[ ], определяет объект-мас- сив char[12], объявляет ссылку line на массив с элементами типа char и связывает эту ссылку с объектом-массивом.

После определения массива его элементы получают умалчиваемые значения. Для элементов арифметических типов по умолчанию устанавливаются нулевые значения, для элементов типа char – значения ‘\0’, для элементов логического типа

– значения false, для элементов типа string – пустые строки, для элементов с типами ссылок и для элементов типа object – значения null.

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

// 07_01.cs - массивы инициализация по умолчанию using System;

class Program

{

static void Main()

{

bool [] bar = new bool[5]; Console.WriteLine("bar[2] = " + bar[2]); int[] integers = new int[14];

Console.WriteLine("integers[0] = " + integers[0]); double[] points = new double[8]; Console.WriteLine("points[7] = " + points[7]);

}

}

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

bar[2] = False integers[0] = 0 points[7] = 0

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

100

Г л а в а 7

 

 

При создании экземпляра (объекта) типа массивов разрешена его явная инициализация, т.е. общий вид выражения с операцией new таков:

new тип [размер-массива] инициализатор;

Инициализатор не обязателен, поэтому ранее мы применяли операцию new без него. Инициализатор – заключенный в фигурные скобки список инициализирующих выражений. Инициализатор имеет вид:

{список_выражений}

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

Пример:

double a=1.1;

double [4] x=new double [4] {2.0/4, 3.0, 4.0,a};

Здесь x – ссылка на массив с элементами типа double, элементы имеют значения:

x[0]==>0.5, x[1]==>3.0, x[2]==>4.0, x[3]==>1.1.

Тот же результат получится, если удалить из обеих квад-​ ратных скобок размер массива 4. Дело в том, что если размер массива не указан, то он определяется количеством инициализирующих выражений.

Для объявления экземпляра массива с применением инициализатора допустима и зачастую используется сокращенная форма без явного использования операции new:

тип [ ] имя_ссылки_на_массив = инициализатор;

Как и ранее инициализатор – заключённая в фигурные скобки последовательность выражений, разделённых запятыми. Размер массива в этом случае может быть явно не указан и определяется числом выражений.

Пример:

long[ ] g = {8/4, 3L, 4, (int)2.4};

Массивы

101

 

 

Тот же результат можно получить, явно применив операцию new:

long [ ] s = new long []{8/4, 3L, 4, (int)2.4};

В одном объявлении могут быть определены несколько однотипных ссылок на массивы с одинаковыми типами элементов:

byte [ ] x, y, z;

Инициализация массивов допустима и при таком определении нескольких однотипных ссылок в одном объявлении, например:

int [] b={1,2,3,4,5}, z=new int [] {6,7,8,9}, d=z;

Определяя ссылки на массивы и массивы как объекты, необходимо помнить их различия. Компилятор в стеке выделяет память для каждой ссылки при ее объявлении, а память в куче для объекта-массива выделяется только при явном (или неявном) применении операции new.

В данном примере ссылки d и z адресуют один и тот же массив (объект класса, производного от Array) из четырех элементов типа int. Таким образом, к одному и тому же элементу массива в нашем примере возможен доступ с помощью двух ссылок. В результате выполнения операторов

d[3]=43;

Console.WriteLine("z [3]="+ z [3]);

будет выведено z [3]=43.

Обратите внимание на тот факт, что у объекта-массива (т. е. у той конструкции, которую называют массивом) нет имени. Ссылка на массив не является уникальным именем экземпляра массива, ведь с массивом могут быть ассоциированы одновременно несколько ссылок.

К массивам (которые являются на самом деле частным случаем контейнеров или коллекций) применим еще не рассмотренный нами оператор цикла, вводимый служебным словом foreach. Формат этого оператора:

foreach (тип имя_переменной in ссылка_на_массива) тело_цикла

102

Г л а в а 7

 

 

Взаголовке цикла используется ссылка на уже существующий одномерный массив, тип элементов которого должен соответствовать типу, указанному перед именем переменной. Тело цикла – это либо отдельный оператор (завершаемый обязательной точкой с запятой) либо блок – заключенная в фигурные скобки последовательность операторов. В заголовке оператора цикла конструкция тип имя_переменной определяет переменную цикла с выбранным программистом именем. Эта переменная автоматически последовательно принимает значения всех элементов массива, начиная с элемента, имеющего нулевой индекс. Для каждого из значений выполняется тело цикла. Количество итераций цикла определяется числом элементов массива.

Определенная в заголовке цикла переменная доступна только в теле цикла, и там ее значение может быть использовано. Однако, попытки изменить с помощью обращений к этой переменной элементы массивы будут безуспешными. Переменная цикла foreach получает значения элементов массива, но не может их изменять.

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

// 07_02.cs массивы одномерные и цикл foreach using System;

class Program

{

static void Main()

{

char[] hi = {'H','e','l','l','o',',',' ','C','#','!',}; foreach(char ch in hi)

Console.Write(ch);

Console.WriteLine();

}

}

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

Hello, C#!

Обратите внимание, что при объявлении объекта-массива и адресующей его ссылки hi выполнена инициализация массива, и не потребовалось явно применять операцию new.

Массивы

103

 

 

До сих пор мы рассматривали массивы, размеры которых определялись при их создании – инициализацией либо явным указанием числа элементов. При выполнении операции new число элементов массива может быть задано не только константой, но и каким-либо выражением. Наиболее типичный случай

– размер массива определяет пользователь, вводя нужное для решения задачи числовое значение.

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

do { цифра = число%10; число = число/10;

}

while(число!=0);

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

Если добавить в тело цикла оператор, преобразующий цифры в символьное представление, то получим изображение числа в обратном порядке, т.е. для числа 753 получим цифры ‘3’, ‘5’, ‘7’. Чтобы получить последовательность цифр в нужном порядке, можно использовать массив с элементами типа char. Размер массива заранее неизвестен и определяется значением (длиной) обрабатываемого числа. Длину числа (число цифр) можно вычислить, используя десятичный логарифм. В языке C# это можно сделать с помощью метода с заголовком double Math.Log10(double value). Метод возвращает значение double, а размер массива должен быть задан целым числом, поэтому придется выполнить приведение типов.

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

// 07_03.cs массив с заранее не определенным

размером using System; class Program

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]