Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП / ООП_Лекции.doc
Скачиваний:
55
Добавлен:
08.06.2015
Размер:
1.03 Mб
Скачать

Многомерные динамические массивы

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

var A2: array of array of integer;

определяет двумерный динамический массив.

Один из способов отвести память под такой массив — исполь­зовать ту же процедуру SetLength, которая использовалась для одномерного массива, но передавать ей в качестве параметров не один, а несколько размеров. Например, оператор

SetLength(A2,3,4);

задает размерность массива 3 на 4.

Доступ к элементам многомерных динамических массивов осуществляется так же, как и для статических массивов. Напри­мер, А2[1,2] — элемент, лежащий на пересечении второй строки и третьего столбца (индексы считаются от нуля, так что индекс 1 соответствует второй строке, а индекс 2 — третьему столбцу).

Можно создавать и более интересные объекты — непрямоуго­льные массивы, в которых, например, второй размер не постоянен и варьируется в зависимости от номера строки. В этом случае сна­чала процедурой SetLength задается первый размер. Например, оператор

SetLength(A2,3);

задает первый размер — 3. В памяти отводится место под 3 стро­ки — 3 динамических массива А2[0], А2[1] и А2[2]. Размеры каждого из этих массивов еще не определены. Далее можно, на­пример, задать размер первого из них равным 4:

SetLength(А2[0],4);

а размер следующего, например, равным 5:

SetLength(A2[1],5);

В качестве примера приведем программу построения и запол­нения нижней треугольной матрицы произвольного размера N.

var А2: array of array of integer;

N,il,i2,m: integer;

begin

N:=3; m:=l;

SetLength(A2,N); {Задание числа строк = N}

for il:=0 to N do {Цикл по строкам}

begin

SetLength(A2[il],il+1) {Число столбцов равно номеру строки)

for i2:=0 to il do

begin

A[i1,i2] :=m; {Заполнение строки}

Inc(m); {Увеличение m на 1}

end;

end;

end;

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

1

2

3

4

5

6

Типvariant

Object Pascal является строго типизированным языком. Но в нем имеется тип variant, отступающий от этого правила. В пере­менных типа variant могут храниться данные любых типов, кро­ме записей, множеств, статических массивов, файлов, классов, ссылок на классы, указателей и Int64. Иначе говоря, перемен­ные типа variant могут хранить все, кроме структур, указателей и Int64. Они могут также хранить объекты СОМ и CORBA, обеспечивая доступ к их методам и свойствам. Могут они также хранить динамические массивы и специальные массивы variant, о которых будет рассказано ниже.

Например, если определить тип переменной V как variant, то могут выполняться такие операторы:

V: variant; // тип V не определен (равен Unassigned)

….

V := 5; // тип V становится равным integer

….

V := lelO; // тип V становится равным real

….

V := Editl.Text;// тип V становится равным string

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

Переменные типа variant занимают 16 битов и содержат код типа и значение переменной или указатель на это значение. В мо­мент создания эти переменные инициализируются специальным значением Unassigned. Значение переменной null свидетельству­ет о неизвестном или ошибочном значении переменной.

Переменные типа variant могут использоваться в выражени­ях как операнды любых операций, кроме ^, is и in, совместно с другими величинами типов variant, integer, real, string, Boole­an. Компилятор в этих случаях автоматически осуществляет приведение типов величин в выражении. Если оба операнда опе­рации имеют тип variant и один или оба операнда равны null, то результат операции тоже равен null. Если один или оба операнда имеют значение Unassigned, то генерируется исключение. Если в бинарной операции только один из операндов имеет тип vari­ant, то другой тоже преобразуется в тип variant.

Приведение типов при вычислении выражений, содержащих операнды variant, осуществляется обычным образом. Например, если VI и V2 типа variant содержат данные типов integer и real, то выражение VI + V2 вернет значение real.

Узнать действительный тип значения переменной variant можно с помощью функции VarType, возвращающей значение типа TVarData, содержащее код типа. Запись TVarData опреде­лена в модуле System. Имеется также предопределенная констан­та varTypeMask, сложение которой по операции and с перемен­ной типа TVarData возвращает истинный тип переменной. На­пример, выражение

VarType(V) and varTypeMask = varDouble

вернет true, если в переменной V в данный момент хранится зна­чение типа double или массив значений типа double.

Возможные значения типов, возвращаемые функцией VarTy­pe, следующие:

VarEmpty переменная в состоянии Unassigned

varNull з начение переменной равно null

VarSmallint тип Smallint

varlnteger тип Integer

varSingle тип Single

varDouble тип Double

varCurrency тип Currency

varDate тип TDateTime (дата и время)

varOLEStr ссылка на динамически размещенную строку UNICODE

varDispatch ссылка на автоматический объект (указатель на ин­терфейс IDispatch)

varError код ошибки операционной системы varBoolean тип WordBool

varUnknown ссылка на неизвестный объект СОМ (указатель на ин­терфейс lUnknown)

varByte тип Byte

varString ссылка на динамически размещенную строку в стиле Pascal (тип AnsiString).

varTypeMask битовая маска для извлечения кода типа

varArray бит, устанавливаемый при ссылке на массив variant

varByRef бит, устанавливаемый при ссылке на тип variant

Теперь остановимся на массивах типа variant. Переменной типа variant нельзя присвоить значение обычного статического массива. Это можно сделать только специальными функциями VarArrayCreate и VarArrayOf. Функция VarArrayCreate опре­делена следующим образом:

function VarArrayCreate(const Bounds: array of Integer;

VarType: Integer): Variant;

Здесь параметр Bounds является массивом, содержащим чет­ное количество целых чисел, каждая пара которых определяет нижнее и верхнее значения индекса массива (точнее, размерно­сти массива, если массив многомерный). Параметр VarType определяет тип элементов массива. Он может принимать значе­ния, приведенные выше в таблице, кроме varString, varArray, varByRef. Например, операторы

var V: Variant;

….

V := VarArrayCreate([0,9], varlnteger);

создают в переменной V типа variant массив из десяти целых чи­сел. Операторы

var A: Variant;

….

А := VarArrayCreate([О, 3], varVariant);

А[0] := 1;

А[1] := 1234.5678;

А[2] := 'Привет! ' ;

А[3] := True;

Labell.Caption:=А[0];

Label2.Caption:=A[2];

создают в переменной А типа массив из четырех значений типа variant, в которые можно заносить и затем использовать значе­ния различных типов.

Функция VarArrayOf определена следующим образом:

function VarArrayOf(const Values:

array of Variant): Variant;

Она возвращает одномерный массив элементов, задаваемых параметром Values. Например, приведенный выше пример мож­но дополнить операторами

А[3] := VarArrayOf([1, 'Приветик!', 100, 1000]);

LabelS.Caption:=A[3][1];

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