Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Программирование на языке Delphi_1.doc
Скачиваний:
43
Добавлен:
28.03.2015
Размер:
710.14 Кб
Скачать
      1. 2.13.6. Вариантные массивы

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

Значениями элементов вариантного массива могут быть любые допустимые для варианта значения, кроме строк varstring. Значениями элементов вариантного массива могут быть и варианты, а это значит, что в таком массиве могут одновременно храниться данные разных типов (и в том числе строки). Например:

var

V: Variant;

begin

// Создаем одномерный вариантный массив с 5 элементами:

V := VarArrayCreate([0, 4], varVariant);

// Наполняем его:

V[0] := 1; //Тип целый

V[1] := 1234.5678; //Тип вещественный

V[2] := 'Hello world'; //Строковый тип

V[3] := True; //Логический тип

//Пятым элементом исходного массива сделаем еще один массив:

V[4] := VarArrayOf([1, 10, 100, 1000]);

Caption := V[2]; //Hello world

IbOutput.Caption := IntToStr(V[4][2]); //100

end;

Действия с вариантными массивами можно осуществлять с помощью процедур и функций. Приведем некоторые:

function VarArrayCreate(const

Bounds: array of Integer; VarType: Integer): Variant;

Создает вариантный массив из элементов типа VarType с количеством и границами измерений, указываемых параметром Bounds

function VarArrayDimCount(const

A: Variant): Integers;

Возвращает количество измерений вариантного массива А или 0, если А не массив

function VarArrayHighBound(const

A: Variant; Dim: Integer): Integer;

Возвращает верхнюю границу индекса вариантного массива А по измерению Dim

function VarArrayLowBound(const

A: Variant; Dim: Integer): Integers;

Возвращает нижнюю границу индекса вариантного массива А по измерению Dim

function VarArrayOf(const Values:

array of Variant): Variants;

 

 

Создает одномерный вариантный массив по перечню значений, содержащихся в открытом массиве Values. Нижняя граница индексов вариантного массива в этом случае равна 0

    1. 2.14. Указатели

      1. 2.14.1. Понятие указателя

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

1. Любая переменная в памяти компьютера имеет адрес. Переменные, значением которых является адрес в памяти (в частности, адреса других переменных), принято называть указателями. Указатели объявляются точно так же, как и обычные переменные:

Var

P1: Pointer; // переменная-указатель нетипизированный

N: Integer; // целочисленная переменная

P: ^Integer; // переменная - указатель типизированный

Переменная P занимает 4 байта и может содержать адрес любого участка памяти, указывая на байты со значениями любых типов данных: Integer, Real, string, record, array и других. Если указатель указывает на переменную структрированного типа (массив, запись…), то этот указатель содержит адрес первого элемента этой структуры.

Чтобы инициализировать переменную P, присвоим ей адрес переменной N. Это можно сделать двумя эквивалентными способами (для P и P1):

P := Addr(N); // с помощью вызова встроенной функции Addr

или

P1 := @N; // с помощью оператора @

В дальнейшем мы будем использовать более краткий и удобный второй способ.

2. Если некоторая переменная P содержит адрес другой переменной N, то говорят, что P указывает на N. Графически это обозначается стрелкой, проведенной из P в N (рисунок выполнен в предположении, что N имеет значение 10):

Рисунок. Графическое изображение указателя P на переменную N

3. Теперь мы можем изменить значение переменной N, не прибегая к идентификатору N. Для этого слева от оператора присваивания запишем не N, а P вместе с символом ^:

P^ := 10; // Здесь не нужно приведение типа

Integer(P1^) := 10; // Выполонено приведение типа

Символ ^, записанный после имени указателя, называется оператором доступа по адресу. В данном примере переменной, расположенной по адресу, хранящемуся в P, присваивается значение 10. Так как в переменную P мы предварительно занесли адрес N, данное присваивание приводит к такому же результату, что и

N := 10;

4. Отдельно обратим внимание на символ ^.

^typeName; // Для описания типизированного указателя

pointer^; // Оператор доступа по адресу

5. При записи P: ^Integer переменная P по-прежнему является указателем, но теперь ей можно присваивать адреса только целых переменных. В данном случае указатель P называют типизированным, в отличие от переменных типа Pointer, которые называют нетипизированными указателями. При использовании типизированных указателей лучше предварительно вводить соответствующий указательный тип данных, а переменные-указатели просто объявлять с этим типом.

type pointerTypeName = ^type;

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

Type

PPerson = ^TPerson;

TPerson = record

FirstName: string[20];

LastName: string[20];

BirthYear: Integer;

end;

var

P: PPerson;

Переменная P, описанная с типом данных PPerson, является указателем и может содержать адрес любой переменной типа TPerson. Впредь все указатели мы будем вводить через соответствующие указательные типы данных. Типом Pointer будем пользоваться лишь тогда, когда это действительно необходимо или оправдано.