Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция 12 ВТ и П.doc
Скачиваний:
4
Добавлен:
22.07.2019
Размер:
1.15 Mб
Скачать

3.Пользовательский тип данных.

При написании программы программист может объявить свой собственный тип данных, который будет построен на основе стандартных типов. Например, мы хотим, чтобы наши переменные могли принимать значения только в диапазоне с -10 до 10. Тогда мы должны объявить свой тип данных, которому мы дадим собственное имя, которое в приведённом ниже примере носит название «interval»:

Type

interval=-10..10;

Слово Type в языке Pascal является зарезервированным и после него идёт наше название типа и перечисление возможных значений или интервала.

Раздел объявления нового типа данных должен (начинающийся со слова type) находиться перед разделом объявления переменных. После того, как мы задали тип данных, мы можем задавать переменные этого типа, например:

Type

interval=-10..10;

Var

x: interval;

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

Если мы хотим ввести тип данных с определёнными значениями, мы можем их перечислить в явном виде, например:

Type

color=(yellow, red, white, black);

Var

y,m: color;

Таким образом, наши переменные y и m могут принимать одно из значений типа color:

y:=red;

m:=yellow;

При этом считается, что значения данного перечислимого типа данных написаны по возрастанию, то есть применение операции y>m даст истинное значение (true).

А пример ниже иллюстрирует вывод на экран значения переменой m:

Case m of

Yellow: writeln(‘Жёлтый’);

Red: writeln(‘Красный’);

White: writeln(‘Белый’);

Black: writeln(‘Чёрный’);

End;

Тип данных массив.

Представим, что нам нужно работать с набором элементов одинакового типа, например, в библиотеке с авторами представленных в этом заведении книг или в поликлинике с номерами карт. Мы могли бы заводить под каждого автора или номер свою переменную, но это очень неудобно, поскольку мы можем заранее не знать, сколько будет авторов и номеров, и, кроме того, описать несколько тысяч переменных (если их будет слишком много) мы будем не в состоянии. Для того, чтобы предусмотреть работу с большим количеством данных одного и того же типа, программисты широко используют специально созданный для этого тип данных, который называется «Массив».

Массивом называется набор элементов одного типа, объединённых одним именем. Тип данных массив – это один из самых важных типов данных в любом языке программирования, поскольку реальные программы очень часто подразумевают использование многих массивов, хранящих самые разные данные. Доступ к каждому элементу массива возможен по уникальному индексу данного элемента. Массив описывается как пользовательский тип данных. При этом указывается базовый тип массива (тип всех его элементов) и интервал индекса, по которому можно определить число элементов массива и метод их нумерации:

Type

Massiv=array[1..10] of integer;

В этом примере мы назвали наш массив “Massiv”, определили количество его элементов (с 1 до 10, всего 10 элементов) и их базовый тип integer. Теперь все элементы нашего массива принадлежат целому типу integer..

Теперь нужно задать переменной наш тип:

Var

h, f: massiv;

Переменные h и f теперь являются массивами и к ним применимы специфические операции, которые мы рассмотрим на этом и следующих уроках.

Слова “array” и “of” зарезервированы в языке для описания массивов, и в русском эквиваленте их можно определить как «массив из» элементов типа integer.

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

h[4]:=15;

После совершения в программе данного операнда значение четвёртого элемента нашего массива h станет равно 15-ти. Для обращения к элементу можно записать его индекс и в неявном виде:

i:=4;

h[i]:=15;

Результат выполнения этих двух действий будет такой же, как и действия, описанного выше.

Индексировать массив можно любым целочисленным, перечислимым или интервальным (диапазонным) типом данных:

type

massiv1=array[byte] of Boolean;

massiv2=array[char] of real;

massiv3=array[red,yellow] of char;

Massiv1 будет содержать 256 элементов (с 0 по 255-ый) и все его элементы могут принимать всего 2 логических значения – истину или ложь (true или false):

var d: massiv1;

d[56]:=false;

Как видите, совершенно необязательно заполнять все элементы массива, а также заполнять их по порядку.

Massiv2 будет содержать также 256 элементов (с 0-го по 255-ый символ) дробного типа данных real:

Varg: massiv2;

g[‘k’]:=23.56;

Massiv3 будет содержать 2 символа:

var s: massiv3;

s[red]:=’p’;

Можно записать так:

var d: massiv1;

i: byte;

i:=1*9

d[i*5]:=true;

В этом случае элементу massiv1 с номером 9*5=45 будет присвоено значение истины. Как видите, индекс можно формировать в процессе выполнения программы.

Значение элементов массива можно вводить и выводить, как это сделано ниже:

readln(d[16]);

writeln(d[20]);

С помощью первого оператора мы вводим значение 16-го элемента массива d, а с помощью второго операнда выводим значение 20-го элемента.

Обратите внимание, что важно следить за тем, чтобы индекс не вышел за допустимые пределы массива. Например, применение операции:

d[i*10]:=false;

зависит от того, чему будет равно значение iв момент определения индекса элемента, которому мы хотим присвоить значение false. Если i будет больше 25, то обращение к элементу массива с номером 260 (26*10) и выше будет ошибкой, поскольку у нас всего может быть 255 элементов.

Ввод и вывод массивов.

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

Заполнение массива иллюстрирует следующий фрагмент программы:

Type

Ar=array[1..14] of byte; // массив, состоящий из 14-ти элементов типа

// byte

Var

m: ar; //переменная m имеет заданный выше тип ar

i: 1..14;

Begin

Writeln(‘Введите 14 целых чисел массива через пробелы’);

Write(‘->’);

For i:=1 to 14 do

Read(m[i]);//каждый раз прочитываем по следующему элементу

//и заполняем им наш массив

Writeln(‘Массив введён’);

Readln;

End.

Точно так же можно и вывести наш введённый массив:

For i:=1 to 14 do

write(m[i]);

Операции и работа с массивами.

Посмотрим некоторые наиболее часто используемые операции, выполняемые над данной структурой.

Представим, что вы храните большую коллекцию именованных кружек и решили написать для неё программу, которая будет эту коллекцию обрабатывать (например, сортировать по возрастанию, по дате появления в коллекции или производить иные действия). В этом случае каждой кружке мы определяем одну ячейку в массиве данных, который назовём kruzki:

Type

kruzki=array[1..2000] of word;

Var

a: kruzki;

w: word;

Пускай у каждой кружки с именем будет свой собственный номер. Здесь мы завели массив с расчётом на максимальное количество кружек 2000, в каждой из ячеек которого будет храниться номер кружки (типа word).

У нас появились некоторые задачи:

Нам нужно поменять 2 кружки местами. Мы знаем номера ячеек, хранящих эти кружки – i1 и i2.

Чтобы поменять местами кружки, нам нужно ввести дополнительный элемент w, куда мы сначала вытолкнем первую кружку, затем на её место поместим вторую кружку и только потом на место второй поместим первую – которую теперь содержит только элемент w:

w:=a[i1];

a[i1]:=a[i2];

a[i2]:=w;

Нам нужно найти кружки с минимальным и максимальным номерами и поменять их местами. Для этого мы изначально считаем, что минимальный и максимальный номер носит первый элемент массива – первая кружка, а затем организуем цикл, который пройдёт по всем элементам и сравнит их номера. Если какой-то номер окажется больше или меньше текущего максимального и минимального соответственно, тогда текущий максимальный и минимальный индекс такой кружки меняется на индекс такого элемента. Рассмотренный ниже пример иллюстрирует данный алгоритм:

const m=2000;

Var

a: kruzki;

w: word;

i, m, i min, i max: 1..m; // imin и imax – индексы минимального и// максимального эл-та

Begin

imax:=1;

imin:=1;

For i:=2 to m do

begin

if a[i]>a[imax] then imax:=i;

if a[i]<a[imin] then imin:=i;

end;

w:=a[imax];

a[imax]:=a[imin];

a[imin]:=w;

End;

Нам нужно сдвинуть все элементы массива влево на единицу. В этом случае первый элемент вылетит (пропадёт) из массива, а последний дублируется:

Алгоритм, выполняющий данную процедуру, показан ниже:

For i:=1 to (m-1) do

a[i]:=a[i+1];

Если мы хотим произвести сдвиг на k элементов (k раз), то в этом случае мы можем воспользоваться вложенным циклом:

For j:=1 to k do

For i:=1 to (m-1) do

a[i]:=a[i+1];

Или использовать такой алгоритм:

For i:=1 to m-k do

a[i]:=a[i+k];

Теперь мы сдвигаем все элементы вправо.

В этом случае пользуемся обратным циклом:

For i:=n down to 2 do

a[i]:=a[i-1];

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

w:=a[1];

For i:=1 to (m-1) do

a[i]:=a[i+1];

a[n]:=w;

Давайте посмотрим, как занести в наш массив новую кружку. Допустим, сейчас в нашем массиве n кружек. Понятно, что это количество должно быть заведомо меньше максимального числа кружек m. Когда мы вставляем новый элемент, текущее количество кружек нужно не забыть увеличить на 1. Если мы вставляем кружку не в новую ячейку, а в какую-нибудь текущую занятую ячейку, то нам также нужно позаботиться и о том, чтобы сдвинуть все элементы вправо, начиная со следующей после ячейки, в которую производится вставка:

For i:=n+1 down to p+1 do

a[i]:=a[i-1];

p – это номер позиции, с которой производится вставка.

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

For i:=p to n-1 do

a[i]:=a[i+1];

n:=n-1;