Документирование - один из наиболее болезненных аспектов программирования. Большинство программистов, написав, оттестировав и внедрив программу, со спокойной душой переходят к следующему проекту. Однако пользователи часто приходят к выводу, что документация неполна, неточна и не соответствует программе.
Документация программ должна состоять из информации, которая позволяет понять и использовать эту программу.
Обычно различают внешнюю документацию, предназначенную для лиц, желающих пользоваться программой, не вникая в ее подробную организацию, и внутреннюю документацию, предназначенную для тех, в чью обязанность входит ее внутреннее понимание, например, в целях ее отладки на конкретной машине и в конкретной операционной системе, трансляции ее для другой ЭВМ или модификации. Комментарии, включаемые в программу, могут быть отнесены к внутренней документации.
Профессиональные программисты при разработке программ должны руководствоваться методиками, изложенными в Государственных стандартах ЕСПД (Единой Системы Программной Документации).
Ограниченный объем рабочего учебника не позволяет рассмотреть вопросы построения сопроводительной документации к программе. Ограничимся рекомендациями по использованию комментариев в программе.
Так как комментарии разрабатываются самим программистом по мере написания операторов программы, то важно рассмотреть этот вопрос подробнее.
Хотя желательность комментариев очевидна, однако некоторые программисты их опускают с целью экономии времени. Иногда они утверждают, что “комментарии будут вставлены позже”. Но такая отговорка неубедительна, поскольку уже через некоторое время автор программы забывает многие ее детали.
Программы с подробными пояснительными комментариями значительно легче отладить, так как они содержат дополнительную информацию для работы с программой.
Некомментируемая программа - это, вероятно, наихудшая ошибка, которую может сделать программист, она говорит о том, что программист - дилетант.
Общее правило при написании комментариев - вставлять их, чем больше, тем лучше, в скобках по мере написания операторов.
Хорошие комментарии написать непросто. Так как цель комментариев - облегчить понимание программы, они должны быть так же хорошо продуманы и проработаны, как и кодировка самой программы. Комментарии нужны как на стадиях проектирования и отладки программы, так и позже при ее модификации и сопровождении.
Существуют три типа комментариев: вводные, оглавления и пояснительные.
Вводные комментарии. Каждая программа, функция или процедура должна начинаться с комментариев, поясняющих ее назначение. Минимальная информация, содержащаяся в вводных комментариях, должна включать следующие пункты:
1) назначение программы;
2) указания по вызову программы и ее использованию;
3) список и назначение основных переменных и массивов;
4) указания по вводу-выводу, список всех файлов;
5) список используемых подпрограмм;
6) название применяемых математических методов, а также ссылки на литературные источники, в которых содержится их описание;
7) сведения о времени выполнения программы;
8) требуемый объем памяти;
9) специальные указания оператору;
10) дата написания и сведения об авторе.
Оглавление. В тех случаях, когда программа большая (десяток и более страниц листинга), целесообразно в ее начале помещать оглавление в виде комментариев. Оглавление должно содержать наименования функций, процедур, блоков, модулей программы и страницы их расположения в тексте.
Пояснительные комментарии. Пояснениями нужно сопровождать те части программы, которые трудно понять без комментариев. Например, это могут быть существенные для понимания логики программы циклы или сложные структуры условных операторов. В комментарии указывается принадлежность структуры с указанием действия, которое производится. Каждый логически выделенный фрагмент программы следует комментировать. Комментарии должны объяснять цель группы операторов программы, а не описывать действия, производимые этими операторами.
Подробнее см. работы [1 - 4].
ПРОЦЕДУРЫ
Описание процедуры, общие положения
Программы, которые не разделяются на отдельные структурные элементы, называются монолитными. Большие монолитные программы сложны для разработки, отладки и сопровождения.
В больших программах часто встречаются фрагменты, одинаковые по выполняемым действиям и различающиеся только в значениях исходных данных. При таком построении программы приходится задавать фактически одну и ту же группу операторов для каждого повторения фрагментов одного предназначения. Для эффективного программирования подобных повторений фрагментов в языках программирования введено понятие подпрограммы. Подпрограмма - это группа операторов, оформленных как самостоятельная программная единица. Подпрограмма записывается однократно в определенной части программы, а затем в нужных местах программы обеспечивается только обращение к ней. Таким образом, подпрограмма - это эффективное средство экономии памяти. При обращении к подпрограмме в нее передаются исходные данные, а после выполнения операторов подпрограммы в основную программу передаются результаты расчетов. Использование аппарата подпрограмм позволяет сократить объем и улучшить общую структуру программы с точки зрения наглядности и читаемости, уменьшить вероятность ошибок и облегчить процесс отладки программы. Разложение монолитной программы на подпрограммы дает возможность выполнять разработку отдельных подпрограмм разными программистами и во многом независимо друг от друга.
Кроме того, подпрограмма может быть рассмотрена как самостоятельный блок, что позволяет использовать ее в общем подходе при конструировании алгоритма и программы по принципам нисходящего или восходящего проектирования. В языке Паскаль подпрограммы реализуются в виде процедур и функций.
Иногда программы, состоящие из процедур и функций, называют модульными. В Турбо Паскале есть специальное понятие модуля, под которым понимается автономно компилированная программная единица, которая в своем составе может иметь и свой раздел описаний и свои подпрограммы. Поэтому, используя термин модуль, следует пояснять, что при этом имеется в виду: или модуль - подпрограмма, или модуль - автономно компилируемая программная единица. На наш взгляд, чтобы исключить путаницу с терминами, целесообразно подпрограмму рассматривать как самостоятельный блок. Но термин модуль также имеет право на существование.
Процедуры и функции, входящие в программу, могут содержать свои подпрограммы и вызвать процедуры и функции более низкого уровня и т.д. Последовательное структурирование программы продолжается до тех пор, пока реализуемые подпрограммами алгоритмы не станут настолько простыми, чтобы их можно было легко запрограммировать. Таким образом, программа приобретает иерархическую структуру. Именно такие программы в литературе принято называть блочными (модульными). Программисты с большим практическим опытом предпочитают использовать такие программы, поскольку они легче для разработки, проще для понимания и легко подвергаются, модификации.
Процедуры. Определения
В Турбо Паскале процедурой называется часть программы, предназначенная для решения определенной задачи или подзадачи.
Процедура в Паскале имеет структуру, подобную структуре программы. Известно, что в стандартном Паскале программы имеют жесткий формат:
Program имя программы
Label метки;
Const объявление констант;
Type определение типов данных;
Var объявление переменных;
объявления подпрограмм;
BEGIN
тело программы
END.
Наличие всех пяти составляющих объявлений - Label, Const, Type, Var, подпрограммы (procedure и function) - в вашей программе необязательно. Однако для стандартного Паскаля, если они присутствуют, порядок их следования строго регламентирован, и в программе они должны присутствовать только один раз. За секцией объявлений следуют подпрограммы и только затем тело программы.
Turbo Pascal обеспечивает более гибкую структуру программы. Главное - оператор Program должен быть первым, а тело программы последним. Порядок описания остальных составляющих жестко не регламентирован, но идентификаторы должны быть объявлены до их использования во избежание ошибок компиляции.
Общая структура процедуры будет иметь вид:
Procedure имя процедуры (параметры); {Заголовок процедуры}
Label метки;
Const объявление констант;
Type определения типов данных;
Var объявления переменных;
Процедуры, входящие в данную;
Begin
Тело главной процедуры;
End;
Таким образом, процедура состоит подобно основной программе из заголовка процедурой программного блока. Заголовок процедуры в отличие от заголовка программы не может быть опущен. Он имеет вид:
PROCEDURE < ИМЯ > (<СПИСОК ПАРАМЕТРОВ>);
где PROCEDURE - служебное слово; ИМЯ - имя процедуры, определяемое в соответствии с общими правилами построения идентификаторов; СПИСОК ПАРАМЕТРОВ (формальных) - перечень имен для обозначения исходных данных и результатов работы процедуры с указанием их типов.
Допускается описание процедуры, не содержащее <СПИСКА ПАРАМЕТРОВ>:
PROCEDURE < ИМЯ >;
в этом случае парамедры в процедуру и из нее передаются через систему глобальных параметров (см. ниже).
Сразу за заголовком подпрограммы может следовать одна из стандартных директив ASSEMBLER, EXTERNAL, FAR, FORWARD, INLINE, INTERRUPT, NEAR.
Параметры в списке заголовка отделяются друг от друга точками с запятой. Если параметры однотипны, то их можно объединять в подсписки и записывать через запятую. Например:
Procedure Sub (a:real; b:real; n:integer; k:integer; ch:char);
можно записать проще:
Procedure Sub (a,b:real; n,k:integer; ch:char);
Операторы тела подпрограммы рассматривают список формальных параметров как своеобразное расширение раздела описаний: все переменные из этого списка могут использоваться в любых выражениях внутри подпрограммы.
Содержательная часть процедуры представляет собой блок и состоит, следовательно, из раздела описаний (меток, констант, типов, переменных, процедур и функций) и раздела операторов, представляющего собой составной оператор Begin - End, в котором для обеспечения наглядности программы слова Begin и End целесообразно записывать с заглавной буквы. Заканчивается блок процедуры точкой с запятой.
Обращение к процедуре
Если процедура объявлена, то в программе ее можно использовать многократно, просто задавая ее имя и, если необходимо, список аргументов, т.е. вызов происходит с помощью оператора вызова:
<ИМЯ ПРОЦЕДУРЫ> (<СПИСОК ПАРАМЕТРОВ>);
где ИМЯ ПРОЦЕДУРЫ - имя процедуры, к которой происходит обращение; СПИСОК ПАРАМЕТРОВ (фактических) - перечень конкретных значений (выражений) и имен, подставляемых на место формальных параметров процедуры при ее выполнении.
При описании подпрограмм и вызова их используются понятия формальных и фактических параметров.
Формальные параметры - это переменные, фиктивно (формально) присутствующие в процедуре и определяющие тип и место подстановки фактических параметров.
Фактические параметры - это реальные объекты программы, заменяющие в теле процедуры при ее вызове формальные параметры.
Над этими объектами и производятся действия, предусмотренные операторами тела процедуры.
При вызове процедуры формальные параметры, указанные в ее заголовке, заменяются аргументами в порядке их следования: первому слева параметру в списке ставится в соответствие первый аргумент, второму - второй и т.д. Число и тип формальных и фактических параметров должны обязательно совпадать.
Вызовами или обращениями к процедурам называются операторы, использующие процедуры. Вызов процедуры приводит к выполнению операторов, составляющих тело процедуры. После этого управление переходит к оператору, следующему за вызовом процедуры.
Пример 2.1. Допустим, требуется вывести на экран горизонтальные двойные линии для построения таблицы (табл. 2.1) длиной 40 символов. Таких линий в шапке одной таблицы по крайней мере две. Кроме того, в таблице используется и одинарная линия той же длины.
Рассмотрим два способа составления программы для решения этой задачи. Первый ориентирован на создание монолитной программы, второй -модульной.
Таблица 2.1
Рассмотрим монолитную программу построения таблицы.
Программа 1 (первый вариант).
Program shapka; {монолитная программа}
Var
I: Integer;
Begin
WriteIn(‘ Таблица 2.1’);
Writeln; {Пропуск строки}
FOR l:=1 to 40 DO {вычерчивание}
Write (‘=’); {двойной линии}
writeln; {Установка курсора на начало строки}
writeIn(‘ № п/п Наименование Шифр Значение, ‘);
writeIn(‘ измерения см ‘);
FOR I:=1 to 40 DO {вычерчивание}
Write (‘=’); {двойной линии}
writeln; {Вывод номеров граф}
writeIn(‘ 1 2 3 4 ’);
FOR l:=1 to 40 DO {Вычерчивание}
Write (‘–’); {одинарной линии}
Writeln; {перевод курсора на новую строку}
End.
Но можно оформить вывод линий с помощью процедуры, а саму процедуру включить в состав программы.
Программа 2 (второй вариант).
Program shapka_procedur; {Блочная программа}
Ch:char; {Глобальные параметры, исп. в процедуре}
Len:lnteger; {Глобальные параметры, исп. в процедуре}
{————————————————————————————————————}
Procedure Lin; {Процедура вычерчивания линий}
Var l:lnteger; {описание локальной переменной}
Begin
FOR l:=1 TO Len DO
write(Ch);
writeln;
End; {конец процедуры}
{————————————————————————————————————}
BEGIN {начало главной программы}
writeIn('Таблица 1');
writeln;
Len:=30; {Задание длины вычерчиваемой линии}
Ch:=’=’; {Задание символа вычерчивания линии}
Lin; {Вызов процедуры вычерчивания линии}
{..вывод текста шапки}
Lin; {Вызов процедуры вычерчивания линии}
{..вывод номеров граф}
Ch:=’_’; {Задание символа вычерчивания линии}
Lin; {Вызов процедуры вычерчивания линии}
END. {Конец главной программы}
В приведенном примере оператор процедуры осуществляет только ее вызов. Исходные данные передаются в процедуру каждый раз с помощью переменных Len, Ch, описанных и определенных в теле основной программы, содержащей обращение к этой процедуре, т.е. с помощью глобальных переменных.