Материал: Основы разработки программных средств в среде Delphi. Романов А.В

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

3.3.4. Массивы

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

Объявление статического массива имеет вид:

var <имя>: array [<ограниченный тип>,...] of <тип элементов>;

Например:

var A: array [1..10] of integer; //одномерный массив

A2: array[1..10,1..3] of integer; //двумерный массив

{массив с индексом перечислимого типа:}

Type color=(red,yellow,green);

var ACol: array [color] of integer;

Ch: array ['a'..'z'] of char; //массив символов

Доступ к элементам массива осуществляется по индексам. Например, A[i] или A2[4,3].

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

Var A1 : array[0..10] of integer =

(1,2,3,4,5,6,7,8,9,10,11);

Const A1 : array[0..10] of integer =

(1,2,3,4,5,6,7,8,9,10,11);

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

Const S:array[0..3] of char = ('A','B','C','D');

Const S:array[0..3] of char = 'ABCD';

При задании начальных условий для многомерных массивов список значений по каждой размерности заключается в скобки, например:

type Ar3 = array[1..4,1..3,1..2] of integer;

const A3: Ar3=(((0,1),(2,3),(4,5)),

((6,7),(8,9),(10,11)),

((12,13),(14,15),(16,17)),

((18,19),(20,21),(22,23)));

Отметим, что в конструкциях, подобным объявлению константы A3, легко запутаться в открывающих (закрывающих) скобках. В Delphi существует специальное сочетание клавиш Alt+[ (Alt+]), позволяющее осуществить поиск соответствующей открывающей (закрывающей) скобки.

Многомерный динамический массив определяется как динамический массив динамических массивов и т.д. Например, определим двумерный динамический массив:

var A2: array of array of integer;

Для выделения памяти под динамический массив необходимо использовать процедуру SetLength, передавая ей в качестве параметров несколько размеров. Например, для задания динамического массива размерностью 3 на 4 для объявленной переменной A2 необходим оператор

SetLength(A2,3,4);

Отметим, что можно создавать и непрямоугольные массивы, в которых, например, второй размер не постоянен и варьируется в зависимости от номера строки [1].

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

procedure MyProc(A: array[1..10] of Integer);

будет расценено как синтаксическая ошибка и вызовет соответствующее сообщение компилятора. Правильное объявление:

type ta = array[1..10] of Integer;

procedure MyProc(A: ta);

Функции и процедуры в Object Pascal могут воспринимать в качестве параметров не только массивы фиксированного размера, но и так называемые открытые массивы, размер которых неизвестен. В этом случае в объявлении функции или процедуры они описываются как массивы базовых типов без указания их размерности. Например:

procedure SumArray(A:array of integer;

var B: array of integer);

При таком определении передаваемый в функцию первый массив будет копироваться и с этой копией – массивом A будет работать процедура. Второй открытый массив определен как var. Этот массив передается по ссылке, т.е. он не копируется, и процедура будет работать непосредственно с исходным массивом. Открытый массив воспринимается в теле процедуры или функции как массив с целыми индексами, начинающимися с нуля. Размер массива может быть определен функциями Length – число элементов и High – наибольшее значение индекса. Очевидно, что всегда High = Length - 1.

При вызове функции или процедуры с параметром в виде открытого массива можно использовать в качестве аргумента конструктор открытого массива, который формирует массив непосредственно в операторе вызова. Список элементов такого конструктора массива заключается в квадратные скобки, а значения элементов разделяются запятыми. Например, функцию Sum, объявленную в специальном математическом модуле Math как

function Sum(const Data: array of Double): Extended;

которая суммирует элементы числового массива, можно вызвать следующим образом:

Sum([1.2,4.45,0.1]);

3.3.5. Множества

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

Например, если множество возможных единичных символов, которые могут быть получены в ответ на вопрос программы "Yes/No", содержит символы y, Y, n и N, то это множество можно описать конструктором ['y','Y','n','N']. Для определения, принадлежит ли переменная множеству, служит операция in. Например, проверить, дал ли пользователь один из допустимых ответов, можно оператором:

if (key in ['y','Y','n','N'])

then <оператор, выполняемый при допустимом ответе>

Множества могут содержать не только отдельные значения, но и ограниченные типы. Например, если необходимо контролировать символы, вводимые пользователем при вводе целого положительного или отрицательного числа, можно определить множество ['0'..'9', '+', '-'] и использовать его, например, при обработке события OnKeyPress любого окна редактирования с помощью следующего кода:

if not(Key in ['0'..'9', '+', '-']) then Key:=#0;

Подобный оператор не позволяет пользователю ввести символы, отличные от имеющихся в множестве.

В приведенных операторах множество использовалось непосредственно, заранее не объявляясь в виде типа. Но если, например, в приложении в ряде мест надо проводить проверки, аналогичные приведенным выше, то целесообразнее объявить переменную или типизированную константу типа множества или тип множества и несколько переменных этого типа. Объявление типа множества делается в форме set of <базовый тип>. Приведем примеры.

var K: set of Char=['0'..'9', '+', '-']; // Объявление

глобальной переменной с инициализацией

// Объявление типизированной константы

const K1: set of Char=['0'..'9', '+', '-'];

// Объявление типа множества

type TDigit = set of '0'..'9';

var D1, D2: TDigit; // и переменных этого типа

Далее в программе допустимы следующие операторы.

...

if ((key in K)OR(key in K1)) then ...

...

D1:=['0','1'];

D2:=['2'..'9'];

Помимо операции in для множеств определен еще ряд операций: объединение, пересечение, операции отношения и ряд других (табл. 3.5).

Таблица 3.5.

Обозначение

Операция

Типы операндов

Тип результата

Пример

+

объединение

Set

Set

Set1+Set2

разность

Set

Set

S-T

*

пересечение

Set

Set

S*T

<=

подмножество

Set

Boolean

Q<=MySet

>=

включающее множество

Set

Boolean

S1>=S2

=

эквивалентность

Set

Boolean

S2=MySet

<>

неэквивалентность

Set

Boolean

MySet<>S1

in

является элементом

порядковый, Set

Boolean

A in Set1

В указанных операциях действуют следующие правила.

  1. Z является элементом X+Y, если он является элементом X или Y, или и X, и Y.

  2. Z является элементом X-Y, если он является элементом X, но не является элементом Y.

  3. Z является элементом X*Y, если он является элементом и X, и Y.

  4. Выражение X<=Y возвращает true, если каждый элемент X является элементом Y.

  5. Выражение X>=Y эквивалентно выражению Y<=X.

  6. Выражение X=Y возвращает true, если X и Y содержат точно одни и те же элементы. В противном случае true будет возвращено выражением X<>Y.

3.3.7. Файлы

Различают файлы трех видов: текстовые файлы, типизированные файлы и нетипизированные файлы.

Текстовые файлы состоят из последовательностей символов, разбитых на строки. В Object Pascal предопределен тип TextFile, соответствующий текстовому файлу. Таким образом, объявление файловой переменной может иметь вид:

var <имя файловой переменной>: TextFile;

Работа с текстовыми файлами осуществляется процедурами и функциями файлового ввода/вывода. Основные процедуры чтения – Read, ReadLn, Write и WriteLn.

Типизированные файлы являются двоичными файлами, содержащими последовательность однотипных данных. Объявление файловых переменных таких файлов имеет вид:

var <имя файловой переменной>: file of <тип данных>;

var F: file of real; // пример

Процедуры чтения и записи Read и Write для типизиро­ванных файлов не отличаются от соответствующих процедур для текстовых файлов. Не определены процедуры Readln и Writeln, но есть процедура Seek, позволяющая перемещаться по файлу не только последовательно, как в текстовых файлах, а сразу переходить к требуемому элементу. Имеется также функция FilePos, возвращающая текущую позицию в файле.

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

var <имя файловой переменной>: file;

Открытие нетипизированных файлов осуществляется процедурами Reset и Rewrite, синтаксис которых несколько отличен от аналогичных процедур для других видов файлов тем, что в этих процедурах указывается размер одной записи в байтах. Для записи и чтения данных в нетипизированных файлах имеются процедуры BlockRead и BlockWrite, которые читают или записывают указанное в них число записей.

3.3.8. Указательные типы

Указатель является величиной, указывающей на некоторый адрес в памяти, где хранятся какие-то данные. Указатели бывают типизированные, указывающие на данные определенного типа, и нетипизированные (типа pointer), которые могут указывать на данные произвольного типа. Используются указатели обычно для работы с объектами в динамически распределяемой области памяти, особенно при работе с записями.

Объявление указателя имеет вид:

type <имя типа указателя> = ^<тип данных>;

F1 = ^real; // типизированный указатель

F2 = pointer; // нетипизированный указатель

Предопределена операция @, возвращающая адрес своего операнда: переменной, функции, процедуры, метода. Иначе говоря, операция @ создает указатель на свой операнд. При этом если X – переменная, то @X возвращает адрес X, причем при директиве компилятора {$T–} (включена по умолчанию) тип результата pointer. В случае функции или процедуры с именем F – @F возвращает точку входа, причем тип результата всегда pointer. Также существует предопределенная константа nil, которая обычно присваивается указателям, которые в данный момент ни на что не указывают.

Чтобы получить доступ к данным, на которые указывает типизированный указатель, надо применить операцию его разыменования. Она записывается с помощью символа ^, помещаемого после указателя. Например, для того, чтобы по адресу объявленного типизированного указателя на тип real F1 находилось какое-либо число, необходим оператор вида F1^:=0.18;. Операция разыменовывания не применима к типу pointer. Для разыменовывания подобного указателя сначала необходимо привести его к другому типу.

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

Источник: https://studfile.net/preview/16568022/