В интерфейсной части описываются также:
- Константы Типы Переменные Процедуры и функции, которые могут быть использованы при вызове модуля.
В необязательном приложении USES, указываемом после слова interface, перечисляются имена модулей, которые используются в данном модуле.
После USES могут быть разделы объявления констант, типов, переменных, процедур и функций. При объявлении процедуры указываются только их заголовки.
Сами подпрограммы приводятся в исполнительной части.
Исполнительная часть модуля включает тела всех процедур и функций, описанных в интерфейсной части, может включать локальные метки, функции и раздел операторов. Исполнительная часть начинается словом implementation/
После слова USES могут быть указаны используемые в исполнительной части модули. Далее указываются:
- Метки Константы Типы Переменные Процедуры и функции
Если есть необходимость, то включаются также операторы инициализации модуля после описания процедур между ключевыми словами begin – end.
Если операторы инициализации не используются, то после описания процедур ставится end, чем и завершается исполнительная часть модуля и весь модуль в целом.
Если в программе и в модуле используются одноименные переменные, то для обращения к переменным модуля используется префикс имя модуля имя переменной.
Текст модуля хранится в файле с именем модуля и расширением *.pas.
UNIT My. pr.
My. pr. pas
После трансляции модуля получается файл с именем модуля и расширением *.tpu
Пример: Задание с использованием модулей
UNIT mmm;
Interface
Function abc (c:real):REAL;
Implementation
Var
A:real;
Function abc;
Begin
Abc:=c+a;
End;
Begin
Write (‘Введите А’);
Readln(A);
End;
Uses mmm;
Var
C:real
Begin
C:=1;
C:=abc(c);
C:=abc(c);
End.
Здесь перед исполнением программы будет отработана часть инициализации модуля mmm в результате чего переменная А модуля получит значение. Последовательные вызовы модуля abc будут возвращать значения переданного ей параметра, увеличенного на значение А.
Пример:
Необходимо в массиве поменять максимальный и минимальный элементы.
USES UNIT1,UNIT2
Var
i:integer;
begin
change (arr);
for i:=1 to n do
writeln (arr[i]);
End.
UNIT UNIT1;
Interface
Uses UNIT2;
Procedure change(Var arr:mas);
Implementation
Uses UNIT 3;
Procedure change;
Var
i, max, min:integer;
Begin
max:=1;min:=1;
for i:=1 to n do begin
if arr[i]>arr[max] then max:=i;
if arr[i]< arr[min] then min:=i;
end;
SWAP (arr[min], arr[max]);
end;
end.
UNIT UNIT2 ;
Interface
Const n=5;
Type
Mas=array[1..n] of real;
Const
Arr: Mas=(0.5,2,1,3,4);
Implementation
End.
UNIT UNIT3;
Interface
Procedure SWAP(Var x, y:real);
Implementation
Procedure SWAP;
Var
R:real;
Begin
R:=x; X:=y; Y:=R;
End;
End.
Большие программные системы, как правило, пишутся множеством разработчиков и вызывает необходимость организации труда работников и их взаимодействия. Для этого в организациях существуют специалисты - системные аналитики или их отделы.
Системные аналитики подпускаются к проекту разработки программного обеспечения на самых ранних этапах разработки. Его задача: разбить проект на ряд подзадач с достаточно большим уровнем детализации, чтобы каждая подзадача была реализована за конечный срок.
Как правило, этап детализации и декомпозиции исходного проекта приводит к разбиению основного проекта на ряд модулей. Это модуляризация проекта.
Результатом модуляризации является граф взаимосвязи модулей проекта. Основой графа (своеобразным корнем графа) является основная программа или главный модуль проекта. Вершинами этого графа обозначаются модули проекта, дуги, соединяющие вершины показывают взаимосвязь различных модулей между собой.
Дуги обозначаются некоторыми символами для последующей их детализации. Детализация взаимосвязей приводится далее в виде списка процедур, функций, переменных и констант, используемых в родительском модуле, но которые определены в дочернем модуле.
Родительским называется модуль, который использует возможности другого модуля, называемого дочерним.
Для более четкого отображения на графе родительских и дочерних модулей используется направление дуги. Например, от родительского к дочернему.
Дочерние модули имеют 2 части: открытая или интерфейсная, и закрытая или описательная (implementation).
Если у модуля есть свои дочерние модули, то прописываются все дочерние модули этого модуля: interface uses... затем implementation uses...; end.
Описание значений дуг или детализация уровня взаимосвязи модуля как раз и является интерфейсной частью, т. е. системный аналитик описывает каждую дугу примерно следующим образом:
a: interface
procedure soft (A: array):
function min (a, b: integer):integer;
function ...
b...
После этого задачей системного аналитика является передача модулей кодировщикам. В идеале 1 модуль на 1-го кодировщика, либо один "куст" дерева.
При этом системный аналитик должен рассчитывать время кодирования и автоматической отладки каждого модуля. В идеале было бы вовлечено людей в последовательности реализации от самого низшего модуля к самому высшему. Технология называется восходящим кодированием модулей.
Но это бывает редко. Таким образом возникает противоречие, проблема: как кодировать родительский модуль если процедуры и функции модуля дочернего еще не разработаны.
Решение этой проблемы заключается в использовании процедур и функций заглушек с одноименными параметрами и именами, описываемые в interface дочернего модуля.
Процедура, функция заглушка - процедура или функция с пустым текстом, содержащая begin end;
Особенности:
1) в функции заглушке должна быть строка, присваивающая какое-либо значение функции;
2) если процедура или функция содержит параметры переменной, то в теле должно быть несколько операторов присваивания значений этим переменным;
3) обычно в функции заглушке вставляют операторы вывода сообщений на экран либо в некоторый файл.
Тестирование и отладка проектов Delphi
Способы тестирования приложений в Delphi
Тестирование – процесс определения (поиска ошибок) работы программы. Как правило при тестировании известны исходные данные и правильный результат, который должна выдавать программа. Такие данные часто называются тестовыми последовательностями или просто тестами. И цель тестирования как можно больше тестовых последовательностей, проверить работоспособность программы на них.
Отладка – точное определение местоположения ошибок, условия их возникновения и способов их устранения.
Создание надежного приложения
Лучший путь исключения ошибки в программе – это защититься от них еще при написании кода. Надежное приложение – это приложение, создаваемое с возможностью легко и просто отлаживать его. Приведем основные рекомендации, которые помогут уменьшить количество ошибок при разработке программы:
1. приложение должно быть хорошо организованно. Для этого нужно разделить программу на модули. Каждый из которых выполняет определенные задачи.
2. приложение должно иметь «защиту от дурака». Если процедура не может «переварить» некорректные данные и вызвать тем самым крах всей системы необходимо проверять целостность въходных данных, прежде чем работать с ними. Однако, помните неформальное правило: «Если системой сможет воспользоваться каждый дурак, значит только дурак и будет ей пользоваться» - не следует увлекаться чрезмерной защитой, поскольку она будет отбирать дополнительное время и ресурсы необходимые для выполнения более важных задач.
3. используйте отладочный вариант вашей програмы. В отладочной версии программы содержится дополнительный код. Цель которого отследить выполнение программы, убедиться в корректности ее работы и упростить отладку приложения.
Отладочная и коммерческая версии кода
Для добавления отладочного кода в программу в Delphi имеются специальные директивы для компиляторов. Это директивы:
$ IFDEF
$IFNDEF
$ELSE
$ENDIF
$DEFINE
$UNDEF
Для того чтобы эти диретивы не рассматривались языком Pascal, но учитывались компилятором их заклячают в { }.
Назначение:
{$IFDEF <имя>} – проверяет наличие определения ранее директивой $DEFINE ранее переменной <имя>. Если такая переменная была определена с помощью $DEFINE ране, далее компилируется код программы до директивы $ELSE или если ее нет, то до $ENDIF. В противном случае этот код не компилируется и не войдет в программу, а войдет код после $ELSE до $ENDIF.
Директива $IFNDEF действует с точностью наоборот. Определяет не определено <имя>.
$DEFINE <имя> - определяет переменную времени компеляции, а $UNDEF удаляет эту переменную.
Пример: создать приложение, в котором уже используются алгоритмы сортировки, но мы хотим его заменить на алгоритм более быстрый, не совсем отлаженный, при этом мы не хотим портить код уже работающей программы.
{ $DEFINE Debug}- определяет что сейчас программа в отладочной версии.
{ $UNDEF Debug}
.
.
.
DataSet:= GetData; получение файла для сортировки.
{ $IFDEF Debug }
Test ResultSet:= Sort_Good (DataSet); вызываем старую версию.
{ $ENDIF}
ResultSet:= Sort_New (DataSet);
{ $IFDEF Debug}
if not CompereData (ResultSet, TestResultSet) then – проверка совпали ли результаты
Raise Exception. Create (‘сортировка не корректна’);
{ $ENDIF}
Символ или переменную отладки (Debug) можно определить не только с помощью директивы, но и через меню Delphi -> Project/Options/Directories/Conditionals defines.
Этот способ автоматически вставляет директиву DEFINE Debug во все модули. В противном случае в ручную. На компиляцию в отладочном режиме и в общем режиме могут влиять другие параметры Delphi – Project/Options/Compiler. Наиболее важные из них – Optimization – управляет оптимизацией компилятора. В большинстве случаев устанавливают оптимизацию, однако если вы считаете, что из-зи оптимизации получаются ошибки, можно ее отключить. Для того чтобы включить или выключить эту опцию можно локализовать директивы.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 |


