Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по программированию 1.doc
Скачиваний:
307
Добавлен:
11.04.2015
Размер:
27.08 Mб
Скачать

1.4. Общая организация программы и ее запись

Итак, мы рассмотрели сущность структурного программирования, теперь рассмотрим как лучше записать программу, составленную с помощью структурного программирования. Прежде всего отметим, что для ЭВМ форма записи программы безразлична, поэтому можно применить любую форму записи. Следовательно, можно составить программу так, чтобы она была воспринята человеком с наибольшим пониманием. Или другими словами как записать программу так, чтоб облегчить понимание структуры программ.

Основными разновидностями форм записи являются отступы, и изменения числа строк (т.е. применения метода когда несколько операторов записаны в одной строке, или разных строках). В настоящее время уже сложились определенные правила по которым записываются программы. Эти правила получили название так называемого «малого программистского стандарта». Рассмотрим их.

1. Цикл.

Короткие циклы, которые помещаются в одну строку, лучше так в одной строке и записывать: '-

FOR I..... : ......... : NEXT I;

Длинные циклы записываются со смещением тела цикла:

FOR I.....:

Оператор

Оператор

NEXT I

Если у кратных циклов общее начало и/или конец, то их можно записать так:

FOR I.....: FOR J

Оператор

Оператор

NEXT J : NEXT I

Если цикл организован операторами, моделирующими условие «пока», или с помощью операторов IF, то целесообразно его также записывать со смещением вправо тела цикла, аналогично записи оператора FOR

2. Ветвление

Короткие операторы IF записываются в одну строку:

IF . . . THEN . .. ELSE ...

Более длинные ветвления следует записывать так:

IF . . . THEN . ... _

ELSE....

где подчеркивание знак продолжающейся строки.

Длинные операторы IF записываются в операторной форме:

IF ... THEN

Оператор

Оператор

.....

Оператор

ELSE

Оператор

Оператор

.....

Оператор

END IF

3. Обход. Это частный случай ветвления и записывается так же, только без ELSE (или соответствующих ELSE) операторов.

4. Длинные операторы.

Если оператор не помещается в строку, то его продолжение следует записывать со смещением, причем не безразлично, в каком месте сделан перенос. Например:

INPUT А (1), N (1) , SKIP, F (8,3) ,F (3), N_

(2,3),FF

читается хуже, чем

INPUT А (1), N (1) , SKIP, F (8,3) ,F (3), _

N(2,3),FF

5. Объединение в строку.

Если язык позволяет размещать несколько операторов в одной строке, то в строку следует группировать логически связанные операторы, выполняющие законченные действия или родствен­ные функционально.

Очевидно, что запись

I=1

X=RO*COS(FI);

Y = RO * SIN (Fl) ;

читается хуже, чем

I=1

X=RO*COS(FI): Y = RO * SIN (Fl) ;

так как объединение последних двух операторов в строку подчеркивает их функциональное единство (перевод из полярных координат в обычные) и выделяет первый оператор (установка начального значения какого-то ин­декса или счетчика). В строку должны быть сгруппированы операторы так, чтобы каждую строку можно было кратко откомментировать.

Например:

DISKR=SQRT(B**2-4*A*C): А2=2*А ‘ВСПОМОГ. ДЕЙСТВИЯ

XI=(-B+DISKR)/A2: X2=(-B-DISKR)/A2 ‘КОРНИ

6. Группировка внутри строки. Увеличив интервалы между некоторыми операторами, можно дополнительно улучшить восприятие программы. На­пример, если строку начальных значений программы записать

МАХТ=С: MINT=D: IMAXT=0: IMINT=0

или

МАХТ=С: IМАХТ=0: MINT=D: IMINT=0

сгруппировав отдельно сведения о максимуме и сведения о минимуме или же разделив значения и индексы, то это читается легче, чем сплошной текст:

ÌÀÕÒ=Ñ: IMAXT=0: MINT=D: IMINT=0

По тому же принципу следует группировать операторы и на схемах: в один линейный блок объединяются функционально родственные вычисления, тогда при программировании переход к новому блоку схемы сопровожда­ется переходом к новой строке программы.

Некоторые авторы (например, [14]) рекомендуют записывать в каждой строке только один оператор. Эта рекомендация безусловно неправильна: историческое разви­тие языков щло от Фортрана, где допускается только один оператор в строке, к Алголу-60, ПЛ/1 и т.д., где допускается несколько операторов в строке, — непонятно, почему этой возможностью не следует пользоваться.

Смещение на каждом шаге лесенки не должно быть большим, обычно оно на уровне следующего лексического слова: четырех — шести позиций вполне достаточно. Такая лесенка хорошо смотрится и на листинге, и на экране дисплея.

Желательно писать программы без меток, но если они встречаются в программе, то должны быть вынесены в начало строки и должны выступать из общего текста программы влево, чтобы их было легко найти. К началу строк выносятся заголовки блоков, начала крупных циклов и крупных составных операторов. Операторы NEXT, END должны размещаться либо в той же строке, что и соответствующий им оператор, например FOR, IF или BEGIN, либо под парным ему FOR, IF или BEGIN.

Для удобства чтения программа должна быть хорошо откомментирована. Можно предложить следующие правила комментирования.

1. Каждая программа или подпрограмма должна начинаться с коммента­рия, в котором на русском языке записано, что делает эта программа.

2. Идентификаторы должны быть мнемоничны (хорошая мнемоника очень существенно дополняет комментарии). За заголовком программы или подпрограммы должны быть откомментированы все основные идентифика­торы и расшифрована их мнемоника. Например: NSTR — номер обрабатыва­емой строки.

3. В тексте программы должны размещаться комментарии, представля­ющие собой краткий заголовок, характеризующий действия, выполняемые до следующего комментария. Комментирование каждого оператора бес­смысленно, так как оно может только повторить то, что делает этот опе­ратор и что можно понять, прочтя оператор. Если операторы позволяют понять, как работает программа, то комментарий должен пояснить, что и зачем делают эти операторы. Например, для программы решения системы линейных уравнений методом Гаусса примерно на 60 операторов текста достаточно четырех комментариев: "Цикл по шагам", "Пересчет строки", "Перестановка строк", "Обратный ход: вычисление Х (1)", связывающих фрагменты текста программы с основными этапами алгоритма.

4. Все выдаваемые программой печати должны быть с поясняющими словами: вместе с содержимым переменных должны печататься либо их идентификаторы, либо поясняющий текст на русском языке — такой текст служит хорошим комментарием как к результатам работы программы, так и к тексту операторов вывода.

Для удобства пользования программой следует хорошо продумывать ввод-вывод. Помимо поясняющих слов на выводе следует обеспечить естест­венность форматов:

матрица должна печататься по строкам в виде матрицы (а не в одну строку),

на одном файле должно помещаться целое число строк многомерно­го массива (например, матрицу размером 5Õ5 не следует вводить по 7 чисел со строки) и т.д.

Программа может быть оформлена как единая головная программа или же из нее могут быть выделены подпрограммы, наконец, вся программа может быть оформлена как процедура. Такое оформление алгоритма или его части в виде процедуры обычно преследует одну из сле­дующих целей:

а) придание алгоритму общности,

б) сокращение общего объема программы за счет возможности одной процедурой обрабатывать различные переменные, массивы и т. д„

в) сокращение времени разработки и отладки программы за счет парал­лельного программирования и отладки процедур,

г) сокращение времени трансляции: отлаженная процедура записывает­ся в библиотеку или выдается файлом в транслированном виде и более не транслируется.

Для получения достаточно универсальных и удобных в использовании процедур необходимо оформлять их с учетом некоторых правил.

1. Обмен данными с процедурами. Для получения процедурой данных из другой программной единицы и для выдачи в другую программную единицу полученных результатов служат параметры (к которым мы отнесем также глобальные переменные и общие области). Прочие работающие в про­цедуре идентификаторы никакого отношения к совпадающим по названию идентификаторам других программных единиц не имеют. Параметры - это "окна во внешний мир", через которые процедура получает исходные данные и отдает свои результаты.

Параметры можно разделить на две группы: а) входные, через которые процедура получает исходные данные; б) выход­ные, через которые она отдает результаты своей работы.

Некоторые параметры могут относиться одновременно к обеим группам. Таким образом, в параметры следует включать только те переменные, через которые идет обмен информацией с другими программными единицами. Все прочие переменные, которые используются в процедуре, в параметры включать не следует, так как использование этих переменных — это внут­реннее дело процедуры и больше эти переменные никого не интересуют.

2. Процедуры-функции. Процедуры, которые выдают в качестве резуль­тата только одно значение (не массив), оформляются как функции. У функ­ции на один формальный параметр меньше, так как в качестве выходного параметра используется идентификатор функции. Функция удобнее в исполь­зовании, так как ее результат можно непосредственно использовать в выра­жении без предварительного присваивания.

3. Ввод-вывод в процедурах. Процедуры содержат операторы ввода-вывода в редчайших случаях. Исключение составляют только процедуры, специально созданные для ввода-вывода, например, процедура печати графика на принтере своим единственным результатом имеет напечатанный график.

4. Проверка применимости алгоритма. Многие алгоритмы могут не давать результата в ряде случаев (например, система линейных уравнений не всегда имеет решение). Процедуры, реализующие такие алгоритмы, имеют свои особенности программирования. Общий принцип заключается в том, что при любых исходных данных процедура должна доработать до конца и вы­дать либо результат, либо сообщение о невозможности получить результат. Из этого вытекают два следствия.

Следствие 1. Там, где может случиться аварийная ситуация, должны быть предусмотрены соответствующие проверки и действия по устранению или обходу этой ситуации или же выдаче сообщения. Например, при реше­нии системы линейных уравнений по компактной схеме Гаусса необходимо делить элементы строки на диагональный элемент. Если этот элемент бли­зок к нулю, то возникнет аварийная ситуация (переполнение или деление на нуль), в результате которой программа будет снята с решения. Следо­вательно, перед делением надо проверить этот элемент на близость нулю и при необходимости выполнить перестановку строк, а если подходящей для перестановки строки нет, то выдать сообщение о неразрешимости системы.

Следствие 2. Процедура, реализующая алгоритм, который может не дать результата, должна иметь дополнительный (сигнальный) параметр, по которому определяют успешность работы процедуры. Этот выходной пара­метр обычно бывает целой или логической переменной или меткой. Целесообразно параметр объявлять логической переменной, если ошибка зависит от одного фактора. Если причин неразрешимости несколько и существенно то, по какой из них невозможно получить резуль­тат, то параметр лучше сделать целой переменной, принимающей значения: 0 — ес­ли решение получено, 1 — если система несовместна, 2 — если решений беско­нечно много и т.п. (иногда можно помимо выдачи признака аварийной ситуации через параметр выполнить печать причины в самой процедуре, но возврат в обратившуюся программу и сигнальный параметр остаются обязательными). Наконец, параметр может быть меткой, по которой происходит вы­ход при неразрешимости системы. Однако следует помнить, что вариант с меткой нарушает структурность обращающейся к процедуре программы.

Чтобы лучше понять, к чему приводит нарушение описанного принципа, представь­те, что Вы попросили товарища узнать время отправления самолета, рейс оказался отложенным на неопределенное время и товарищ уехал домой, не сообщив Вам ничего: Вы же просили узнать время, а ему не удалось.