
- •Литература
- •Содержание
- •1. Основные понятия ооп
- •2. Программирование для Windows
- •3. Визуальное программирование и среда Delphi
- •Создание приложений в средеDelphi
- •Компоненты общего назначения tMainMenu- главное меню формы (программы)
- •TPopupMenu- вспомогательное (локальное) меню
- •TLabel- метка для отображения текста
- •TEdit-ввод и отображение строки
- •TMemo- ввод и отображение текста
- •TButton- кнопка
- •TBitBtn- кнопка с изображением
- •TSpeedButton- кнопка для инструментальных панелей
- •TCheckBox- независимый переключатель
- •TRadioButton- зависимые переключатели
- •TRadioGroup- группа зависимых переключателей
- •TListBox- список выбора
- •TComboBox- раскрывающийся список выбора
- •TPanel- панель
- •TTabControl- набор закладок
- •TPageControl- набор страниц с закладками
- •4. Особенности языка ооп Object Pascal
- •Процедуры и функции Выход из процедур и фукнций и возврат результата
- •Передача параметров
- •Параметры со значениями по умолчанию
- •Перегрузка функций
- •Динамическое распределение памяти
- •Указатели
- •Операции с указателями
- •Операция @
- •Самоадресуемые записи
- •Динамические массивы Одномерные динамические массивы
- •Многомерные динамические массивы
- •Исключения и их обработка
- •Защита кода зачистки в блокахtry...Finally
- •Защита кода зачистки на уровне модуля — разделfinalization
- •Обработка исключений в блокахtry...Except
- •Последовательность обработки исключений
- •5. Классы и объекты
- •Классы и объекты
- •Инкапсуляция
- •Наследование
- •Полиморфизм
- •Составляющие класса Поля
- •Одноименные методы
- •Свойства
- •События
- •Объявление класса
- •Операции с классами
- •Ссылки на классы
- •TObjectи информация о классах
- •Регистрация и обнаружение классов
- •6. Создание объектов во время выполнения, поиск компонентов
- •Клонирование объектов
- •Поиск компонента
- •Двукратное освобождение объекта
- •7. Построение собственных компонентов
- •Как и для чего следует строить компоненты
- •Общие руководящие принципы
- •Ключевые идеи
- •Компиляция компонентов
- •Отладка компонентов
- •Примечание
- •Примечание
- •Примечание
- •8. Работа с потоками
- •Классы потоковDelphi
- •Файловые потоки
- •Примечание
- •Методы потоков в действии: программаMemoStr
- •Потоки памяти
- •Пример программыMemoryS
- •Примечание
- •Написание заказного класса потока
- •9. Работа с com-объектами, использование серверов ole-автоматизации
Многомерные динамические массивы
Многомерный динамический массив определяется как динамический массив динамических массивов динамических массивов и т.д. Например:
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, Boolean. Компилятор в этих случаях автоматически осуществляет приведение типов величин в выражении. Если оба операнда операции имеют тип variant и один или оба операнда равны null, то результат операции тоже равен null. Если один или оба операнда имеют значение Unassigned, то генерируется исключение. Если в бинарной операции только один из операндов имеет тип variant, то другой тоже преобразуется в тип 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.
Возможные значения типов, возвращаемые функцией VarType, следующие:
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];