- •Введение
- •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. Структура типов данных в языке Паскаль
- •Содержание
7.3. Специфика оформления процедур ввода – вывода в модулях
Специфические особенности операций ввода – вывода как операций, преобразующих формуданных, а также основные рекомендации по проектированию процедур ввода – вывода были рассмотрены в § 6.3. Там же приведены основные варианты локализации файловых переменных и операций назначения, открытия и закрытия файлов (табл. 6.1, с. 84).
Оформление таких процедур как внутренних не вызывает особых трудностей, однако размещение процедур во внешних модулях зачастую отнюдь не сводится к простому редактированию текста программы! Такое размещение порождает дополнительные вопросы (и даже проблемы), нуждающиеся в тщательном анализе.
Поэтому рассмотрим упомянутые выше варианты локализации применительно к программе из нескольких компонентов (минимальный вариант - programи одинunit), когда процедуры ввода – вывода вынесены во внешний модуль.
Вариант 1. Файловая переменная объявлена как глобальная. Операции назначения и открытия файлов размещены вне процедуры.
Согласно правилам локализации, глобальные файловые переменные должны быть описаны во внешнем модуле.
Получающаяся при этом программа нехороша тем, что в вызывающем модуле (program) производятся операции с переменными, описания которых отсутствуют в тексте этого модуля. Теряется наглядность, ухудшается контроль правильности описаний; как следствие, снижается надежность программы.
Кроме того, модуль по сути своей должен быть максимально независимым от вызывающей программы, тогда как наличие глобальных объектов привязывает его к ней.
Этот вариант нежелателен.
Вариант 2. Файловая переменная является параметром процедуры. Операции назначения и открытия файлов размещены вне процедуры.
Формально этот вариант лишен недостатков. Файловая переменная локализована в вызывающем модуле. Там же назначается и открывается файл, и в процедуру при вызове как фактический параметр передается файловая переменная открытого файла.
Программа этого варианта приведена в § 7.4 (пример 2).
Но, к сожалению, передача файловой переменной открытого файла между модулями может приводить к непредсказуемым ошибкам обработки файла, причем вероятность появления ошибок растет с совершенствованием операционных и программных систем: вturbo-pascal(подWindows) риск меньше, чем в средеDelphi. Автор сталкивался с такими ситуациями на практике; единичных случаев достаточно, чтобы не рекомендовать использовать такой способ.
● Вариант 3. Файловая переменная объявлена как локальная. Операции назначения и открытия файлов размещены в теле процедуры. Как следствие, закрытие файлов также должно осуществляться внутри процедуры. Проще говоря, все моменты, связанные с файлом, локализованы в процедуре.
К такому варианту процедуры следует стремиться, что не всегда просто.
•• Такая организация процедур несложна в следующих случаях:
процедура вызывается однократно;
при многократном вызове каждый ввод осуществляется из отдельного файла.
То же справедливо для вывода.
Если процедуры ввода – вывода организованы согласно варианту 3, то размещение их в отдельном модуле является простым делом техники.
•• Проблемы возникают, когда операции, связанные с вводом-выводом каких-то данных, разнесены по крайней мере между двумя компонентами (два модуля читают данные из одного файла и т.п.). Именно в такую ситуацию мы попадем, если для задачи mas_3(§ 6.5, пример 2, с. 93) оформим процедуры ввода – вывода в отдельном внешнем модуле. Поэтому воспользуемся этим примером для описания специфики оформления процедур ввода – вывода в подобных ситуациях.
Будем исходить из того, что:
передача между модулями файловой переменной, связанной с открытым файлом, является неудовлетворительным вариантом;
передавать в этом случае следует имя файла (передавать файловую переменную неоткрытого файла бессмысленно);
процедура ввода-вывода, размещенная в отдельном модуле, должна сама назначать, открывать и закрывать файл.
Применительно к нашему примеру это означает, что придется решать вопросы, которые мы легко обошли, оформив процедуры как внутренние.
Ввод трех массивов. Согласно проекту задачиmas_3, все массивы размещены в одном входном файле. При открытии файл устанавливается на начало; если разместить операции открытия внутри процедуры, то при повторных вызовах потребуется пропустить уже считанные данные. Надо как-то фиксировать начало считываемой части данных и передавать в процедуру.
Анализ показывает, что хорошего решения при размещении всех данных в одном файле не получается. Самым рациональным выходом представляется такой.
Каждый массив разместим в своем файле. Имена этих файлов будем задавать как параметры программы: 1-й параметр – файл с массивом а, 2-й – с массивомb, 3-й – с массивомс.
Вывод массивов
При открытии операцией rewriteвыходной файл очищается; следовательно, если поместить операцию открытия внутри процедуры вывода, то каждый последующий ее вызов будет уничтожать результаты предыдущего.
Если выводить массивы каждый в свой файл, в программе необходимо будет создать еще один, итоговый файл, куда запишется заголовок, поочередно перепишутся файлы с массивами, а затем выведутся результаты.
Рациональным выходом представляется такой. Можно в программе (головном модуле) создать файл, выведя в него заголовок, и закрыть его. Тогда процедура вывода массива может открывать этот файл для добавления в конец– операциейappend, по окончании работы – закрывать. Для вывода результатов (уже вне процедуры) снова придется открыть файл операциейappend.
Программа этого варианта также приведена в § 7.4 (пример 2).