Процедуры и функции представляют собой блоки программного кода, имеющие точно такую же структуру, как и программа (единственное отличие заключается в том, что процедуры и функции не могут содержать раздел uses).
В общем виде структура программной реализации процедуры следующая.
procedure MyProcedure(<список параметров>);
const // раздел описания локальных констант
type // раздел описания локальных типов
var // раздел описания локальных переменных
begin
... // программный код процедуры
end;
Функции отличаются от процедур только тем, что их идентификатор возвращает некоторое значение, поэтому при описании необходимо через двоеточие указать тип возвращаемого результата.
function MyFunc(<список параметров>):<тип результата>;
... // разделы описаний
begin
... // программный код функции
end;
Заголовок процедуры (функции) состоит из зарезервированного слова procedure (function), идентификатора и списка параметров, заключенного в круглые скобки (список параметров не обязателен, можно создавать процедуры или функции без параметров). Указываемые в заголовке параметры называются формальными и предназначены для обмена данными между основной программой и процедурой (функцией). В списке указывается один или несколько идентификаторов параметров и через двоеточие – тип. Параметры разных типов отделяются друг от друга точкой с запятой.
procedure prog_id(par1,par3:integer; param3:real);
Количество передаваемых формальных параметров не ограничено, причем внутри процедуры или функции они представляют собой обычные переменные или константы.
Вызов осуществляется с помощью оператора вызова, состоящего из идентификатора процедуры (функции) и списка фактических параметров, перечисляемых через запятую, которые представляют собой переменные или константы, описанные в разрабатываемой программе. Передача параметров производится через стек и может выполняться по значению, по ссылке или объявлением параметра как выходного.
При передаче параметра по значению в стек копируется значение переменной, соответствующей фактическому параметру. Подобный способ передачи принят по умолчанию, т.е. нет необходимости в использовании никаких дополнительных ключевых слов. Значение параметра, переданного по значению, можно изменять внутри процедуры или функции, однако в программу это изменение передаваться не будет. При передаче параметров по значению необходимо соблюдать осторожность, так как при передаче больших структур данных возможно переполнение стека, т.е. возможно возникновение ошибки времени выполнения Stack overflow.
В случае второго способа передачи параметров – по ссылке – в стек заносится не значение параметра, а его адрес. Таким образом, независимо от объема памяти, занимаемого переменной, в стеке будет занято только 4 байта. При передаче параметра по ссылке перед его идентификатором в списке формальных параметров указывается одно из ключевых слов: var или const. В первом случае параметр называется параметром-переменной, во втором – параметром-константой.
Значения параметров-переменных в тексте процедуры (функции) можно изменять, и эти изменения будут передаваться в программу. Таким образом, параметры-переменные используются для передачи данных в вызывающую программу. Значения параметров-констант внутри структуры изменять нельзя. Попытка присвоить параметру-константе какое-нибудь значение приведет к ошибке компиляции.
Еще одним способом изменения внутри процедуры или функции параметров, объявленных в ПО, является использование ключевого слова out. Оно помечает формальный параметр как выходной. Отличие от передачи по ссылке в том, что при этом не гарантируется передача начального значения. Память, занимаемая аргументом, очищается в момент обращения к процедуре. Таким образом, параметр, передаваемый как выходной, указывает на некоторое место в памяти, являющейся просто контейнером, куда процедура должна занести соответствующее выходное значение.
Тип формального параметра в заголовке можно не указывать, например: procedure MyProg(var A). В этом случае в качестве фактического параметра может быть использована переменная любого типа. Параметры без типа передаются только по ссылке. При использовании параметров без типа компилятор не может произвести проверку соответствия типов. Поэтому программист должен сам следить за соответствием типов во избежание возникновения ошибок во время выполнения программы (runtime error).
Формальные параметры могут быть открытыми массивами. В этом случае можно передавать в качестве фактического параметра массивы разной длины. Параметр, имеющий тип открытого массива, объявляется следующим образом:
procedure MyProc(var param:array of Mytype);
К открытому массиву внутри процедуры можно обращаться только поэлементно. Открытые массивы можно передавать как по ссылке, так и по значению. В последнем случае фактический массив записывается в стек, что может привести к ошибке Stack overflow.
В качестве примера работы с открытым массивом приведем функцию [1], которая возвращает строку при передаче в нее аргументов различных типов – строк, целых и действительных чисел, булевых величин, указателей.
function ToStr(A: array of const):string;
var i:integer;
begin
Result:='';
for i:=0 to High(A) do With A[i] do
case VType of
vtString :Result:=Result+VString^+' ';
vtAnsiString:Result:=Result+String(VAnsiString)+' ';
vtPChar :Result:=Result+VPChar+' ';
vtChar :Result:=Result+VChar;
vtExtended:Result:=Result+FloatToStr(VExtended^)+' ';
vtInteger :Result:=Result+IntToStr(VInteger)+' ';
vtBoolean :if VBoolean
then Result:=Result+'true'+' '
else Result:=Result+'false'+' ';
vtObject :Result:=Result+VObject.ClassName+' ';
vtClass :Result:=Result+VClass.ClassName+' ';
vtCurrency:Result:=Result+CurrToStr(VCurrency^)+' ';
vtVariant :Result:=Result+string(VVariant^)+' ';
vtInt64 :Result:=Result+IntToStr(VInt64^)+' ';
end; {case VType}
end;
Вызывать функцию необходимо, используя конструктор открытого массива, в который можно включать самые разные элементы.
Для параметров в объявлениях функций и процедур могут задаваться значения по умолчанию. Этот механизм позволяет передавать не все необходимые аргументы. Значения по умолчанию задаются добавлением в конце объявления параметра знака равенства, после которого записывают константное выражение. Аргументы по умолчанию рекомендуется назначать последними в списке параметров, т.к. при вызове процедуры или функции пропускать параметры нельзя.
Идентификатор функции обычно используется в выражении. В теле функции для возвращения значения используется как сам идентификатор функции, так и неявно определенный идентификатор Result, с которым внутри функции можно работать как с обычной переменной. Идентификатору функции можно только присваивать значения, но нельзя использовать в выражениях в теле функции, иначе функция будет повторно вызывать сама себя. Подобный прием в программировании носит название рекурсия, но пользоваться им надо осторожно, ибо, например, бесконечный вызов функции может привести к переполнению стека.
Процедуры и функции могут содержать не только разделы объявления констант, типов переменных, но и включать в себя объявления функций и процедур. Все эти идентификаторы, называемые локальными, видны только внутри тех процедур и функций, в которых они объявлены.
В одной и той же области видимости можно определить перезагружаемые функции или процедуры. Они имеют одинаковые имена, но различаются по числу и типу параметров. Для объявления функции (процедуры) как перезагружаемой используется ключевое слово overload. Рассмотрим пример.
Function Divide(X,Y:real):real; overload;
Begin
Result:=Y/X;
End;
Function Divide(X,Y:integer): integer; overload;
Begin
Result:=Y div X;
End;
Обе функции объявлены как перезагружаемые с именем Divide. Первая получает действительные аргументы, вторая – целые. Соответственно вызов Divide(3,7) приведет к вызову второго варианта. Первый вариант будет вызван при использовании другого программного кода – Divide(3.0,7.0).
В Delphi интегрированная среда разработки (IDE – Integrated Development Environment) – это удобная среда быстрой разработки сложных прикладных программ, в которой есть все необходимые инструменты (tools) для проектирования, запуска и тестирования разрабатываемых программных средств и все нацелено на облегчение этих процессов. IDE интегрирует в себе редактор кодов, отладчик, инструментальные панели, визуальный редактор форм, редактор графических ресурсов, инструментарий баз данных и многое другое – все, с чем приходится работать при проектировании ПО. Эта интеграция предоставляет разработчику хорошо сбалансированный набор инструментов, дополняющих друг друга. Естественно, существует возможность расширять возможности (меню) IDE, включая в нее необходимые дополнительные инструменты, в том числе и разработанные самостоятельно.
Запуск Delphi осуществляется файлом delphi32.exe или пиктограммой в разделе меню Windows Пуск | Программы. Внешний вид IDE Delphi версии 7.0 показан на рис. 4.1. В верхней части находится главное меню. Ниже расположены две инструментальные панели. Левая панель содержит быстрые кнопки, дублирующие некоторые наиболее часто используемые команды меню. Правая панель содержит палитру библиотеки визуальных компонентов VCL (Visual Component Library), состоящую из ряда страниц, закладки которых видны в верхней части палитры. Правее полосы главного меню размещена панель сохранения и выбора различных конфигураций, содержащая выпадающий список и две быстрые кнопки.
В основном поле окна слева находится окно инспектора объектов (Object Inspector), с помощью которого задаются свойства компонентов (вкладка Properties) и обработчики событий (вкладка Events).
П
равее
расположено окно редактора
программного кода
(Code Explorer),
который является обычным текстовым
редактором, ориентированным на написание
текстов программ.
Важным инструментом разработки интерфейса приложений является визуальный редактор форм (Form Designer). С его помощью можно разместить на форме проектируемого приложения различные компоненты, как показано на рис. 4.1, модифицировать некоторые свойства компонентов и самой формы, установить типовые обработчики событий. Напомним, что компоненты являются основой компонентной архитектуры построения приложений (см. пп. 1.1.5). Обработчик события – это процедура, предназначенная для создания реакции формы или компонента на какое-либо воздействие. Возможные события объектов перечислены на вкладке Events инспектора объектов.
В интегрированной среде разработки Delphi существует достаточно много различных окон, используемых в процессе разработки ПО. Например, окно менеджера проекта (Project Manager) или показанное на рис. 4.1 окно наблюдаемых величин (Watch List). Поэтому в IDE, как и в оконных компонентах Delphi, широко используется технология Drag&Doc – перетаскивание и встраивание окон. Встраивание окон позволяет экономить площадь экрана. Такое окно можно отличить от обычного по следующим признакам:
сокращенная полоса системного меню, включающая обычно только кнопку закрытия окна;
наличие в контекстном меню, всплывающем при щелчке в окне правой кнопкой мыши, переключателя Dockable – встраиваемое (если снять метку с этого переключателя, окно перестанет быть встраиваемым);
при перетаскивании встраиваемого окна размеры его рамки изменяются, если окно перемещается в пределах другого окна.
Главное меню (рис. 4.1) содержит полный набор команд, необходимых для работы в интегрированной среде Delphi. Для полной характеристики всех команд лучше обратиться к справочной литературе [1] или выделить конкретный пункт меню и с помощью клавиши F1 получить контекстную справку.
Поскольку Delphi является визуальной средой проектирования, то частого обращения к командам главного меню, как правило, не требуется. Наиболее востребованные команды в Delphi вынесены на инструментальные панели быстрых кнопок (рис. 4.1). Их назначение можно узнать из ярлычков, появляющихся при задержке курсора мыши над соответствующей кнопкой. Разработчик может изменить набор инструментов на панелях с помощью команды Vien | Toolbars.
Приведем описание основных команд главного меню и (при наличии) соответствующие им пиктограммы быстрых кнопок и "горячие" клавиши активации команды с клавиатуры.
Часть команд меню File
– это обычные команды работы с файлами:
Open
(
),
Save
(
,
Ctrl+S),
Save
as
(
),
Close
(
),
Exit
(
),
назначение которых пояснять не требуется.
Команды Open
Project
(
)
и Save
Project
As
(
, Ctrl+F11)
используются для открытия проектов и
их сохранения под другим именем. Под
проектом в Delphi
понимается набор файлов, необходимых
для разработки программного обеспечения
или динамически связываемой библиотеки.
Команды Save
All
(
,
Shift+Ctrl+S)
и Close
All
(
)
предназначены для сохранения и закрытия
всех открытых файлов, относящихся к
активному проекту.
Команда Use
Unit (
,
Alt+F11)
используется для подключения к проекту
дополнительных модулей, открытых в
редакторе кода.
Команда Print
(
)
предназначена для печати формы или
программы.
Для создания новых проектов и других
файловых элементов программных средств
используется команда New,
с которой связано подменю, позволяющее
создать, например, приложение –
Application
(
),
форму – Form
(
),
программный модуль Unit
(
),
модуль данных – Data
Module
(
),
фрейм – Frame
(
)
и т.п. Выполнение команды Other
(
)
приводит к вызову окна диалога (рис.
4.2), которое позволяет создать файл
любого типа. Здесь разработчику
предлагается набор объектов, содержащихся
в специальном депозитарии – хранилище
объектов (Object
Repository).