- •Введение
- •1. Общие положения
- •1.1. Понятие алгоритма. Данные в задачах и алгоритмах
- •1.2. Понятие о технологии разработки программ. Принципы и этапы разработки программ
- •1.3. Состав документации по отдельным этапам
- •1. Задача
- •9. Структурные тесты
- •1.4. Нисходящая разработка и нисходящая отладка
- •2. Процесс разработки программы на примере решения типовой задачи
- •2.1. Разработка алгоритма и программы уровня 0 с заглушками
- •2. Входные данные
- •3. Выходные данные
- •5. Функциональные тесты
- •6. Метод
- •7. Алгоритм
- •8. Программа на паскале. Диалоговый вариант
- •9. Структурные тесты
- •2.2. Отладка программы с заглушкой
- •2.3. Общая схема перехода от метода к алгоритму решения
- •2.4. Разработка алгоритма и программы для примера
- •2. Входные данные
- •5. Функциональные тесты
- •6. Метод
- •7. Алгоритм
- •8. Программа на паскале
- •9. Структурные тесты
- •2.5. Отладка полной программы
- •2.6. Список заданий
- •3. Организация хранения данных с позиций эффективности отладки и использования программы
- •3.1. Как лучше хранить, вводить и выводить данные
- •3.2. Использование текстовых файлов для хранения входных и выходных данных
- •3.3. Использование параметров в Паскаль-программах
- •3.4. Задание
- •4. Некоторые методы решения типовых задач
- •4.1. Поиск экстремальных значений (максимума, минимума) в одномерном массиве
- •2. Входные данные
- •3. Выходные данные
- •6. Метод
- •4.2. Поиск элемента, удовлетворяющего заданному условию
- •2. Входные данные
- •6. Метод
- •2. Входные данные
- •3. Выходные данные
- •6. Метод
- •4.3. Задача со сложной логикой
- •2. Входные данные
- •3. Выходные данные
- •6. Метод
- •4.4. Упорядочение одномерного массива
- •3. Выходные данные
- •6_А. Метод включения
- •6_Б. Метод пузырька
- •4.5. Список заданий
- •5. Работа с двумерными массивами (матрицами)
- •5.1. Схема обработки матриц
- •5.2. Ввод и вывод матрицы
- •5.3. Пример решения задачи
- •3. Выходные данные
- •6. Метод
- •5.4. Список заданий
- •6. Оформление алгоритмов в виде процедур
- •6.1. Основные положения
- •6.2. Кодирование процедур на языке Паскаль
- •6.3. Специфика оформления процедур ввода – вывода
- •6.4. Рекомендации по оформлению процедур
- •6.5. Примеры разработки процедур
- •3. Выходные данные
- •6. Метод
- •3 Истина, если все элементы строки больше 1, ложь, в противном случае . Выходные данные
- •7. Описание процедуры
- •8. Кодирование на паскале
- •9. Структурные тесты
- •2. Входные данные
- •3. Выходные данные
- •4. Аномалии не рассматриваем
- •6. Метод
- •7. Алгоритм
- •2. Входные данные
- •3. Выходные данные
- •6. Метод
- •8. Кодирование на паскале
- •2. Входные данные
- •3. Выходные данные
- •6. Метод
- •8. Кодирование на паскале
- •2. Входные данные
- •3. Выходные данные
- •6. Метод
- •7. Описание процедуры
- •8. Кодирование на Паскале
- •6.6. Список заданий
- •7. Внешние модули (unit) в турбо-Паскале
- •7.1. Суть и описание модуля
- •7.2. Связь модуля с другими модулями и главной программой. Область действия описаний объектов
- •7.3. Специфика оформления процедур ввода – вывода в модулях
- •7.4. Примеры оформления процедур во внешних модулях
- •7.5. Задания
- •7.6. Обработка многомодульных программ в среде турбо-Паскаль
- •8. Контрольные вопросы к главе 1
- •К главе 2
- •К главе 3
- •К главе 6
- •К главе 7
- •Заключение
- •Литература
- •Приложение 1. Базовые структуры алгоритмов
- •Приложение 2. Простые типы в Паскале
- •Приложение 3. Структура типов данных в языке Паскаль
- •Содержание
6.4. Рекомендации по оформлению процедур
● Процесс проектирования
•• Пусть на некотором уровне проектирования задача разбита на подзадачи.
Решение подзадач относится уже к следующему уровню. Это лучше фиксировать в документации, указывая номер уровня разработки. Исключения допустимы только для очень простых задач.
•• Процесс решения любойподзадачи, начиная с исходной задачи, осуществляется по одной и той же схеме. Продумываются и реализуются одни и те же этапы, результаты которых должны быть в общем случае зафиксированы в одних и тех же пунктах документации.
•• Реально на разных уровнях и для разных подзадач по-разному расставляются акценты на отдельных моментах.
Так, на нулевом уровне проектирования требуется тщательная разработка форм ввода – вывода и присутствуют соответствующие специфические подзадачи преобразования формы данных. Для подзадач следующих уровней это, как правило, не требуется.
Далее, если метод решения подзадачи прост или известен, можно перейти сразу к алгоритму, а возможно, и к программе.
Коротко говоря, все зависит от задачи. Поэтому некоторые шаги могут оказаться вырожденными и в документации их целесообразно только упомянуть либо вообще опустить.
•• При оформлении некоторой подзадачи в виде процедуры дополнительно появляется необходимость:
определить вид процедуры;
задать ей имя;
сформировать заголовок;
записать вызов, заменяющий подзадачу.
Для выполнения этих действий достаточно знать состав входных и выходных данных. Поэтому будем фиксировать их сразу после пункта «Выходные данные» спецификации.
Разработка метода не имеет специфических особенностей. Оформление алгоритма состоит в соблюдении несложных синтаксических правил и при тщательном выполнении предшествующих шагов никаких дополнительных элементов документации не требует.
Для кодирования процедуры на Паскале необходимо определить глобальные типы для параметров нестандартных типов. Эти действия включаются в этап кодирования, так как зависят непосредственно от языка программирования.
● Процедура общего вида или функция?
Вид процедуры определяется по числу выходных значенийсоответствующей подзадачи. Одно значение соответствует одной простой переменной. Несколько значений могут соответствовать как значениям нескольких простых переменных, так и множеству значенийоднойструктурированной переменной (в рамках данного пособия – массива).
•• Если число выходных значений более одного, то следует оформлять процедуру общего вида. Это случай, когда выходные данные подзадачи представлены более чем одной простой переменной или хотя бы одной структурированной переменной.
•• Если подзадача имеет единственное выходное значение, то выбор вида процедуры остается за программистом. Ниже приведены общие соображения, которыми можно руководствоваться.
•• Процедуры общего вида универсальны и проще в оформлении.
Они удобнее также при проектировании, так как вызов такой процедуры – самостоятельный оператор. Поэтому подзадача просто заменяется этим оператором. Оформление функций с этой точки зрения требует ряда дополнительных малополезных и провоцирующих ошибки действий.
•• Оформление функций дает возможность производить операции с результатами вызовов в рамках одного выражения (как, например, в математике при вычислении тригонометрических выражений).
•• Поэтому прежде всего надо проанализировать свой проект и определить, что рациональнее в данной задаче. Как правило, слепое следование установке «один выход – оформляется функция» только провоцирует ошибки.
● Оформление функции
Выходное значение функции передается в вызывающую программу через имя функции. На первый взгляд представляется, что при проектировании функции это имя и следует считать выходным значением. Такой подход приводит к очень распространенной ошибке, суть и причины появления которой попытаемся объяснить.
Логика рассуждений разработчика программы такова.
Если процедура используется в некоторой программе только один раз, то логично для сохранения смысловой нагрузки имен использовать одинаковые имена для фактически вычисляемого значения (в головном модуле) и результата работы процедуры. Если процедура – функция, то это имя станет ее именем.
Например, программист назвал в головном модуле некоторую величину, которую предполагается вычислить с помощью процедуры, delta. Руководствуясь изложенными соображениями, он планирует так же назвать результат процедуры и принимает решение описать процедуру-функцию.
Результат функции передается через ее имя, следовательно, функция будет также называться delta.
Но тогда в головном модуле имя deltaокажется описанным дважды, а при обращении к функции получим выражение:
delta:=delta(........)!
Причина такой ошибки - неверная экстраполяция на случай функции правила о независимости (и, следовательно, возможности совпадения) имен формальных и фактических параметров. Имя функции доступно в головном модуле, в отличие от имен ее формальных параметров.
Поэтому целесообразно проектировать функцию по аналогии с процедурой общего вида:
именовать выходное значение любым именем, в том числе и совпадающим с именем вычисляемого фактического значения;
именовать функцию другим произвольным именем;
обрабатывать выходное значение как локальное и присваивать его по завершении обработки имени функции.
● Выбор имен формальных параметров
•• Имена формальных параметров всегда должны выбираться так, чтобы в итоге наглядно прослеживалось соответствие формальных и фактических параметров при вызове. Сделать это можно по-разному.
•• Если процедура вызывается один раз, то универсальным будет способ формирования имен формальных параметров путем добавления определенных символов к именам фактических.
Например, в задаче обрабатывается массив aизnэлементов (фактические параметры). Соответствующие формальные параметры можно назватьa1иn1.
В частном случае можно просто брать одни и те же имена.
•• То же справедливо, если процедура вызывается несколько раз с одними и теми же переменными – фактическими параметрами (как, например, в задаче Cond_2 из § 4.3, где вызовы стоят в разных ветках и, следовательно, одни и те же переменные имеют разные значения).
•• Если процедура вызывается несколько раз с разными переменными – фактическими параметрами, то лучше для формальных параметров выбрать свои имена.
Такой пример приводится в § 6.3, где одна и та же процедура обрабатывает три разных массива: aизnaэлементов,bизnbэлементов иcизncэлементов. Чтобы массив – формальный параметр не ассоциировался ни с каким из конкретных массивов, но в имени отображалось, что речь идет о массиве, он названmas; число элементов названоn.
Хорошим вариантом именования представляется и такой:
массивы в задаче – a1,a2,a3соответственно изn1,n2иn3элементов;
формальные параметры процедуры – aиn.