- •Литература
- •Содержание
- •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-автоматизации
Операции с указателями
Для указателей PChar определены операции отношения =, <>, <, >, <=, >= . Кроме того для различных указателей определены еще следующие операции:
Обозна- чение
|
Операция
|
Типы операндов
|
Тип результата
|
Пример
|
+
|
сложение указателей
|
указатель на символ, целое
|
указатель на символ
|
Р + I
|
-
|
вычитание указателей
|
указатель на символ, целое
|
указатель на символ, целое
|
P-Q
|
^
|
разыменование указателя
|
указатель
|
указатель на базовый тип
|
р^
|
=
|
равенство
|
указатель
|
Boolean
|
P = Q
|
<>
|
неравенство
|
указатель
|
Boolean
|
Р <> Q
|
Операнд операции разыменования ^ может быть указателем на любой тип. Указатель типа Pointer должен быть сначала преобразован к конкретному типу, после чего его можно разыменовывать.
Выражение Р = Q дает true только в случае, если Р и Q указывают на один адрес. В противном случае выражение Р <> Q дает true.
Операции + и — применяются для увеличения или уменьшения сдвига указателя на символ. Операция вычитания кроме того позволяет найти разность смещения двух указателей. Эти операции подчиняются следующим правилам.
Если I — целое число, а Р — указатель на символ, то Р + I увеличивает на I адрес, на который указывает Р; т.е. возвращается указатель на адрес, отстоящий на I символов от Р. Аналогично, Р - I возвращается указатель на адрес, предшествующий Р на I символов.
Если Р и Q — указатели на символы, то Р - Q определяет число символов между Р и Q.
Операция @
Операция @ возвращает адрес своего операнда: переменной, функции, процедуры, метода. Иначе говоря операция @ создает указатель на свой операнд. При этом действуют следующие правила:
• Если X — переменная, то @Х возвращает адрес X. Если включена директива компилятора {$Т-} (она включена по умолчанию), то тип результата pointer. Если же включена директива {$Т+}, то тип результата ^Т, где Т — тип X.
• Если F — функция или процедура, то @F возвращает точку входа F, причем тип результата всегда pointer.
• При применении операции @ к методу перед идентификатором метода должна идти ссылка на имя класса, например, @TMyCIass.DoSomething.
Самоадресуемые записи
Нередко в памяти надо динамически размещать последовательность записей, как бы формируя некий фрагмент базы данных, предназначенный для оперативного анализа и обработки. Поскольку динамическое размещение проводится в непредсказуемых местах памяти, то такие записи надо снабдить полями, содержащими указатели на следующую аналогичную запись. Такие записи со ссылками на аналогичные записи и называются самоадресуемыми. Ниже приведена схема связи таких структур в последовательность. Полю указателя в последней структуре обычно присваивается значение nil, что является признаком последней структуры при организации поиска в списке.
Приведем пример такой самоадресуемой структуры.
Type
trec=~rec;
rec=record
inl,in2:word ;
s:string[10];
pr:trec
end;
Подобное описание является исключением из общего правила языка Pascal, по которому нельзя использовать в предложениях еще не объявленные типы и переменные. В данном случае первое предложение объявляет тип trec как указатель на структуру типа rec, объявленного после этого. Сразу за этим предложением следует объявление самой структуры. В этом объявлении имеется поле рг, представляющее собой указатель на структуру аналогичного вида.
Приведем пример формирования в памяти списка таких структур. Для этого надо определить три переменные, являющиеся указателями на структуры:
var РО : trec=nil;
Pnew, Pold: trec;
Первая из этих переменных будет всегда указывать на первую структуру в списке. Две остальные переменные — вспомогательные. Если в некоторый момент возникла необходимость динамически разместить в памяти очередную структуру и вставить ее в конец списка, это можно сделать следующим кодом:
New (Pnew); { выделение памяти под новую запись }
with Pnew^ do { заполнение полей записи }
begin
in1:=…;
in2 :=...;
S:=…;
pr:=Nil;
end;
if P0=nil then PO:=Pnew { РО — указатель на первую запись }
else Pold^.pr :=Pnew ; { указатель на очередную запись }
Pold:=Pnew;
Если список еще не начат (РО = nil), то указателю РО присваивается ссылка на вновь размещенную структуру (Pnew). В противном случае ссылка на новую структуру присваивается полю рг предыдущей структуре в списке (Pold). Таким образом новая структура включается в общий список. Полю рг этой структуры присваивается значение nil. Это является признаком того, что данная структура является последней в списке.
Сформировав список в памяти далее легко его просматривать, проходя в цикле по указателям. Легко также делать перестановки записей, их удаление и т.п. Для всех этих операций не надо ничего перемещать в памяти. Достаточно только изменять соответствующие ссылки в полях рг.
Раньше подобные списки широко использовались для создания в памяти стеков, очередей и других упорядоченных списков. Однако, в Delphi введены специальные типы данных TList и TString , которые ведут подобные списки и имеют множество удобных методов для управления ими.