2.16. Кодирование сверху вниз

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

По мере того как "скелет" программы просматривается и проверяется на каждом более низком уровне, формируется фактиче-

2> Davis P. J., Fidelity in Mathematical Discourse: Is One and One Really Two?, American Mathematical Monthly (March 1972).

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

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

2.16.1. ПСЕВДОКОДЫ

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

2.16.2. СОГЛАШЕНИЯ ПО ПСЕВДОКОДАМ

1. Применяйте только структурные конструкции:

а) последовательность г) DO UNTIL б) IF THEN ELSE д) CASE в) DO WHILE e) CALL

2. Для обозначения конца операторов DO используйте END DO, для обозначения конца операторов IF — соответственно ENDIF.

3. Вводите абзацы для обозначения блочной структуры.

Если в какой-либо организации придерживаются установленных соглашений по псевдокодам — любой . может их прочесть. Псевдокоды должны быть частью документации и могут использоваться вместо блок-схем или являться их дополнением. Напишите предлагаемую ниже задачу в псевдокодах.

Задача. Составьте программу вывода на печать сдачи с доллара, если цена покупки меньше доллара. Примите во внимание Желание покупателя получить минимальное число монет.

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

Задача. Считайте последовательность единиц, двоек и троек и подсчитайте их количество по отдельности. Прочитав число 9, на" печатайте результаты.

Решение. г ;

Считать число. DO WHILE (не 9) IF 1 THEN прибавить 1 к содержимому счетчика единиц ELSE IF 2 THEN прибавить 1 к содержимому счетчика двоек ELSE IF 3 THEN прибавить 1 к содержимому счетчика троек

ENDIF ENDIF

Считать следующее число. ENDDO

Вывести на печать результаты.

Обратите внимание на то, что в примере используются только структурные конструкции и как абзацы выделяют структуру. По* пытайтесь выполнить такую же задачу, используя операторы DO UNTIL, CASE или массивы. В дальнейшем псевдокоды должны быть переведены на язык программирования. Псевдокоды используют для получения логического построения программы до начала фактического программирования.

Псевдокоды имеют два преимущества:

1. Логика программы может быть записана полностью независимо от языка программирования и машины.

2. Логика программы изображается таким образом, что ее могут понять даже непрограммисты..

Таким образом, псевдокоды позволяют написать программу в простой структурной форме до того, как выяснятся все слож" яости машины или языка программирования.

Прежде чем программировать, запишите программу в псевдокодах.

Попытайтесь решить еще одну, более сложную задачу.

Задача. Прочитайте какой-нибудь текст, поместите в таблицу все входящие в него слова и подсчитайте, сколько раз встречается каждое слово. Напечатайте таблицу, указывая каждое найденное слово и число его появлений в тексте.

DO WHILE (количество > 0) IF количество >= 50 THEN вычесть 50 из количества Напечатать 50 ENDIF

IF количество > =25 THEN вычесть 25 из количества Напечатать 25 ENDIF

IF количество >" 10 THEN вычесть 10 из количества

Напечатать 10 ELSE

IF количество > =5 THEN вычесть 5 из количества Напечатать 5 ELSE

Напечатать количество установят?? количество равным нулю* ENDIF ENDIF ENDDO

Рис. 2.11. Решение задачи о получении сдачи с доллара. X 16.3. ФАКТИЧЕСКОЕ ПРОГРАММИРОВАНИЕ

Фактическое программирование также следует выполнять^ сверху вниз, причем вначале пишут операторы языка управления заданиями (ЯУЗ), за которыми следует главная (управляющая)-программа. На рис. 2.12 показана сущность подхода сверху вниз*-Обычно разработка "скелета" проекта может выполняться однимг человеком, что обеспечивает целостность разработки. Так как применяется принцип модульности, главная программа должна быть короткой и вызывать модули и подпрограммы, которые можно моделировать, создавая подыгрывающие подпрограммы. Подыгрывающая программа (stub)1) — очень короткая последовательность команд, которая используется как замена, пока не будет-создана фактическая программа. Подыгрывающие программы мо-

2.16. Кодирование сверху вниз

Рис. 2.12. Иллюстрация подхода сверху вниз.

-л — запись операторов языка управления заданиями ЯУЗ и их выполнение; б — добавление операторов языка редактора связей (ЯРС) и их выполнение; в — добавление программного сегмента (написанного на ПЛ/1) с подыгрывающими подпрограммами, его выполнение и продолжение программирования.

гут быть двух видов: фиктивные или замещающие модули. Фиктивные модули (dummy module) не выполняют никакой работы, а только возвращают управление вызывающему модулю. Замещающий модуль (substitution module) выполняет простую обработку до тех пор, пока не окажется возможным программировать более сложный модуль. Необходимо, чтобы вызывающий модуль не мог продолжать работу до тех пор, пока замещающий модуль не выдал результат. Примером могла бы быть ситуация, когда требуется подпрограмма усложненного ввода. Замещающий модуль может выдавать какие-либо простые данные. Эти подыгрывающие программы могут, например, читать фиктивные файлы, где хранятся тестовые данные. Использование обращений к фиктивным подпрограммам позволяет производить компилирование я отладку на более ранней стадии программирования.

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

!) В отечественной литературе используется также термин "заглушка".— Прим. перев.

Подыгрывающая программа может быть любой программой, обеспечивающей возвращение в вызывающий модуль для продолжения его выполнения. Хорошо, если подыгрывающая программа настолько удовлетворяет любым требованиям интерфейса, что в последующем никаких изменений интерфейса не потребуется. Часто такие программы имеют только один или два оператора. Иногда они просто печатают текст: "ВЫПОЛНЕНА ПОДПРОГРАММА ХУ", показывая тестирующему, что подпрограмма как будто выполнена, и проверяя таким образом логику модуля более высокого уровня. В других случаях бывает необходимо вернуть некоторые значения вызывающему модулю с тем, чтобы можно было проверить самый высокий уровень программы, т. е. главную программу. После того как она отлажена, таким же образом программируют и проверяют следующий по порядку более низкий уровень. Части программы более низкого уровня последовательно добавляют аналогичным образом. Очередной модуль программируют только после того, как составлена программа и отлажен модуль, его вызывающий. Этот процесс приводит к тому, что модули самого высокого уровня, обычно более критичные, проверяют наиболее тщательно.

Когда проект разрабатывают сверху вниз, то для программирования модулей само>о низкого уровня можно использовать дополнительно лиц с невысокой квалификацией. Очень важно, чтобы опытные программисты выполняли первоначальную разработку "скелета" программы сверху вниз и его фактическое программирование. Кроме возможности для профессионального программиста показать свое искусство такой подход позволяет менее опытным программистам непосредственно участвовать в работе и иногда даже реализовать свои идеи. Во всяком случае, программа должна быть прочитана и проверена по крайней мере двумя лицами.

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

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

2.16.4. ВЫВОДЫ

Расширение задачи при проектировании сверху вниз всегда затруднительно. Примеры из учебников изображают этот процесс просто перечислением множества расширений сверху вниз. Даже имея дело с этими простыми задачами, я совершенно запутался, пытаясь получить хорошее решение. А у меня были такие -преимущества, как четко определенная задача и хороший алгоритм, чего в реальных условиях обычно нет. Поэтому, если вы деваете расширение сверху вниз, нужно быть готовым к большим трудностям, преодолеть которые не просто. После выбора алгоритма вторым основным условием получения успешной программы является хороший проект. Плохой алгоритм или плохой проект нельзя спасти искусным программированием. Всегда стремятся побыстрее начать программирование, однако от таких порывов следует удерживаться, пока не завершено проектирование. Кодирование— минимальная часть задачи. Большинство решений следует принять до того, как начнется программирование. Как только вы приступили к программированию, трудно изменить направление работы. Поэтому очень важно стать на правильный путь в самом начале. Чаще всего существует более одного способа решения задачи.

Описанная ситуация подобна путешествию по стране в автомобиле. Если вы отправляетесь в поездку, не наметив маршрут, то первоначальное направление, в котором вы начали движение, может определить оставшуюся часть пути. Поэтому важно спланировать заранее, куда и как вы отправитесь сначала.

2.15. Размышления о структурном программировании || Оглавление || 2.17. Бригада главного программиста


Услуги