- •Введение
- •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. Структура типов данных в языке Паскаль
- •Содержание
Введение
В основу предлагаемого вниманию учебного пособия положен материал базового курса «Программирование на языке высокого уровня», читаемого автором студентам компьютерных специальностей АВТИ МЭИ. Пособие преследует двоякую цель:
представить общую схему поэтапного процесса разработки программ, начиная от постановки задачи и кончая отладкой и тестированием программы;
изложить типовые алгоритмы решения основных классов задач.
Содержание и порядок изложения материала соответствуют содержанию и порядку проведения практических и лабораторных работ по курсу в течение первого семестра. Материал объединяют принципиальные теоретические положения, в необходимой степени изложенные в пособии. В полном объеме эти положения являются содержанием лекционной части курса.
Предлагаемые задачи подобраны таким образом, что каждая из рассмотренных схем решения либо покрывает целый класс задач, либо является типовой частью некоторого класса. Например, поэтапная схема разработки и отладки программы (гл. 2) является общей; конкретный пример, на котором она иллюстрируется, может быть распространен на любую задачу обработки одномерных массивов со структурой алгоритма «цикл с разветвлением» и т.д.
Пособие может быть успешно использовано как самостоятельное, вне рамок курса, для практического освоения процесса разработки схем и программ решения общих задач.
При первом чтении можно начать с главы 2, чтобы получить представление о процессе разработки в целом, и обращаться к гл. 1 как справочной.
1. Общие положения
1.1. Понятие алгоритма. Данные в задачах и алгоритмах
Алгоритм– это конечный набор правил, последовательное применение которых позволяет чисто механически решать любую конкретную задачу из некоторого класса однотипных задач.
Необходимые свойства алгоритма:
массовость(алгоритм должен быть применим к некоторомуклассу исходных данных; иначе говоря, исходные данные при различных выполнениях алгоритма могут изменяться в определенных пределах);
детерминированность(процесс применения правил определен однозначно);
результативность(на каждом шаге известно, что считать результатом этого шага).
Программапредставляет собой запись алгоритма на каком-либо компьютерном языке программирования.
Данные– понятие, определить которое в общем случае невозможно. Применительно к процессу разработки алгоритмов данные представляют собой объект обработки для алгоритма (программы).
Какие бывают данные? Чтобы ответить на этот вопрос, надо ввести основание классификации, или признак, разделяющий данные на классы.
Ниже приведено несколько оснований классификации и соответствующих им классов данных.
Константы и переменные(по «постоянству значений»)
Константапредставляет сама себя (что написано, то и есть) и не изменяет значения при выполнении алгоритма. Например, 4 – числовая константа, число «четыре»; ‘а’ – символьная константа, буква “а”; ‘result’ – строковая константа, строка, представляющая слово «result».
Чтобы не приводить абстрактных примеров, воспользуемся текстами приведенных далее алгоритмов. Так, константы в программе задачи «Точки в круге» (гл.2 пособия, § 2.3, с. 20):
числовая константа 100 в конструкции const Nmax=100;
числовые константы в операторах writeln(в описаниях форматов);
там же – строковые константы (тексты в одинарных кавычках).
Переменная– область памяти («ячейка»), имеющая имя. Значение переменной может изменяться; при этом старое значение стирается и заменяется новым. В любой момент переменная имеет некоторое значение, и фраза «значение переменной не определено» означает только, что к моменту первого использования переменная не получила нужного начального значения вследствие небрежности программиста.
За заданием начальных значений должен следить разработчик алгоритма!
Имя переменной– последовательность букв и цифр, начинающаяся с буквы. Например, правильные имена –fd,a12d23,gamma.
В задаче «Точки в круге» переменные – входные и выходные данные и индекс элементов массива. В программе их имена присутствуют в описаниях, размещенных после ключевого слова var.
● Типы данных(по смыслу задачи, по представлению в компьютере)
Здесь будем рассматривать только числовые типы, а именно – целый и вещественный.
Тип данного в задачеобычно можно определить из ее условия. Так, количество каких-либо объектов – целое число; размеры, координаты – чаще всего вещественные и т.д.
При этом числовые данные могут быть представлены как точно, так и приближенно. В случае приближенного представления чисел обязательно присутствуют погрешностиприближений исходных чисел и погрешности результатов их обработки. Вопросами соответствующих оценок приближений детально занимается специальный раздел алгебры; реально такие оценки необходимы там, где точные значения либо не нужны, либо недостижимы.
Точность представления данных зависит от возможностей измерительных приборов (в физике, химии; в геометрии, черчении и т.д). Пусть в простой геометрической задаче с помощью обычной линейки и циркуля требуется определить длину aстороны равностороннего треугольника, вписанного в окружность с радиусомr= 1 см. В данном случае эта длина равна 1,7 см, даже если результат контрольного вычисления по формулеa = rбудет содержать больше знаков.Десятичные знаки после 0,1 неинформативны, так как линейка дает точность не более 0,1.
При разработке компьютерных программ все вопросы приближения данных должны решаться на уровне постановки задачи и анализа результатов работы программы, т.е. внепроцесса разработки программного продукта. В программу решение таких вопросов может быть заложено только в той степени, в какой оно сформулировано до разработки программы. Например, если в полученном результате можно доверять только одной цифре после точки, то можно распечатать все цифры и вручную зачеркнуть лишние; а можно вывести только одну – нужную. Но во втором случае число выводимых цифр должно быть известно до составления программы (тогда, вообще говоря, это будетвходное данное программы, о чем см. ниже)!
Выразить точность задания исходных данных задачи можно двумя способами – указав единицу разряда последней точной цифры числа (той, которой можно доверять) или указав число знаков, которым можно доверять (обычно – знаков после десятичной запятой). Так, число 1,7 представлено с точностью 0,1, или с одним знаком после запятой. В программировании вместо понятия «десятичная запятая» используется понятие «десятичная точка»; соответственно представление числа с точностью 0,1 есть представление с одним знаком после точки.
При вычислениях вручную точность результата определяется математическими правилами. Практически, если задача не является специфической задачей обработки слишком больших или слишком точных чисел, можно руководствоваться следующим правилом: точность результатов выполнения арифметических операций не превосходит точности операндов. Это особенно актуально при вычислениях на компьютере, когда промежуточные вычисления недоступны человеку. В таком случае при анализе результата оставляются только достоверные цифры, а остальные отбрасываются, с округлением или без.
В компьютерецелые и вещественные числа различаются прежде всего не значениями, а способом представления и обработки.
Целые числа представляются точно.
Вещественные числа представляются приближенно, с некоторой точностью, зависящей от технических характеристик компьютера и операционной системы, под управлением которой работает система программирования. Лишние десятичные знаки отбрасываются. Компьютерная точность не зависит ни от программиста, ни, тем более, от постановщика задачи. Узнать ее как правило можно из справочника по системе программирования. Так, в нашем случае это система turbo-pascal, и ознакомиться с представлением вещественных чисел можно, прочитав соответствующий раздел описания языка.
Поэтому важно, чтобы целые по смыслу задачиданные были описаны какцелые в программе; то же относится к вещественным данным. В общем случае должен быть корректно описантип данных.
В разных языках программирования работа с вещественными числами может осуществляться по-разному. Поэтому, строго говоря, сравнивать вещественные числа на равенство в общем случае не следует.
Так, например, сравнение «4.0 = 4.0» в языке Паскаль истинно, а в языке фортран – ложно. Если же в одной из частей равенства находится значение-константа, заданное программистом с некоторой точностью, а в другой – значение, вычисленное с точностью машинной, то результат сравнения будет ложным, даже если с практической точки зрения величины равны. Приведем пример.
Требуется проверить, вписывается ли равносторонний треугольник со стороной ав окружность радиусаr.
Изобразим с помощью циркуля и линейки на обычном листе бумаги несколько таких вписанных в окружности треугольников и измерим той же линейкой стороны треугольников и радиусы окружностей. Так, условие выполнено, например, для а=1,7 см иr=1 см.
Однако в программе для компьютера в условии a = sqrt(3) корень из трех будет вычислен с машинной точностью, заведомо превосходящей точность линейки. Дляа=1,7 см иr=1 см условие (1) приобретет вид: 1.7=1*1.73…. , т.е. окажется ложным! Аналогично обстоит дело и для любого другого треугольника, благополучно вписанного в окружность на бумаге. Получается, что нельзя решить программным путем столь простую задачу?
Выход состоит в правильном сравнении на равенство вещественных чисел с учетом точности их представления.
Два вещественных числа pиq, представленные с точностьюt(t=0,1; 0,01 и т.д. – десятичные знаки, которым можно доверять), равны, если
| p - q| <t/2.
Приведенный пример убедительно показывает, что если в задаче имеются вещественные данные, то при анализе постановки задачи надо указать точность их представления, а при необходимости сравнения вещественных чисел учитывать эту точность. В нашем случае точность равна 0,1 (точность линейки), а условие (1) в программе следует записать так: | a - r | < 0,05 (на языке паскаль:abs(a – r*sqrt(3)) < 0.05).
С любым типом данных связано понятие диапазона значений.
Диапазон данных существует в любой задаче. Нельзя придумать задачу, где данные менялись бы, например, от 1020до 10–20; если это физические данные, то они относятся к разным разделам физики и т.п. Поэтому при корректном подходе к разработке программы диапазоны всех данных должны быть определены в процессе уточнения задачи, до ее решения.
Если это сделано, то задание в алгоритме значений данных, выходящих за границы диапазона, может произойти только вследствие ошибки. Это самая первая и очевидная ситуация ошибки в данных (аномалия). Результаты в этом случае будут лишены смысла.
В общем случае проверка правильности данных, предусмотренная в программе, позволит получить решение при правильных данных и диагностировать ошибки без обработки – при неправильных. Забегая вперед, скажем, что таким образом реализуется свойство надежности алгоритма.
Если в учебных задачах значения диапазонов каких-либо данных не следуют из условия задачи, будем представлять некую мысленную модель и брать эти границы искусственно.
Диапазоны типов данных, определенных в языке программирования, задаются в описании языка. Программист, зная диапазон реальных данных задачи, выбирает соответствующее описание типа этих данных в программе.
Формат. Если диапазон и точность значений данного известны, можно определить схему для представления любого данного из заданного диапазона. Обозначим значком «+» знаковую позицию, крестиками ХХ…ХХ – числовые позиции, а точку представим как она есть.
Формат– схема представления числа из заданного диапазона, занимающего максимальное количество позиций.
Пусть, например, |а| <=100, точность 0,01.
Тогда формат: +ХХХ.ХХ (всего 7 позиций, две после точки; в паскале это кодируется как :7:2 ).
Для целых чисел, естественно, дробная часть отсутствует.
В общем случае формат указывается в программе при вводе и выводе данных, однако разные языки имеют свою специфику. Так, в паскале ввод бесформатный, а неверный формат при выводе игнорируется и число выводится в некотором стандартном виде (не всегда наглядном). В фортране при несоответствии формата ввода и записи вводимых значений либо введенные значения будут искажены, либо программа завершится аварийно, а при неверном формате вывода результатом будут либо икаженные значения, либо – вообще отсутствие таковых и замена их значками *.
● Структура данных(по способу организации данных одного типа)
Простая переменнаяимеет одно имя и одно значение. Будем обозначать простые переменные так:
Описание: цел a; вещ b;
Массив– совокупность однотипных данных, имеющая общее имя. Для идентификации отдельных элементов используютсяиндексы. В простейшем случае это номера элементов. Количество индексов, необходимых для однозначной идентификации элемента, определяетразмерностьмассива.
Одномерный массив– упорядоченная по номерам элементов последовательность. Изобразим одномерный массив следующим образом:
Описание: цел с[5];
Элементы массива: с1,с2, …,с5, в общем виде –сi илис[i].
Двумерный массив (матрица)– структура из строк и столбцов, например:
Описание: цел с[3,5];
Элементы массива: в общем виде – сi,j илис[i,j].
Первым всегда указывается индекс строки.
● Описание данных– типа и структуры – в конкретном языке программирования определяется правилами этого языка.
Использование целых и вещественных типов в языке Паскаль продемонстрировано ниже в примере решения типовой задачи (см. гл. 2).
Базовые типы данных языка Паскаль приведены в приложении 2.
● Входные и выходные данные(по отношению к задаче)
Попробуйте дать определение входных данных. Затем определите входные данные в следующих задачах.
Вычислить объем цилиндра с высотой hи радиусом основанияr.
Вычислить объем цилиндра с высотой h=5 см и радиусом основанияr.
Вычислить объем цилиндра с высотой h=5см и радиусом основанияr=7см.
А теперь приведем определение входных данных, согласно которому Вы можете самостоятельно скорректировать свои ответы.
Входные данные– это данные,
без конкретных значений которых невозможно получение конкретного результата («посчитать и получить число»);
конкретные значения которых не заданы в условии задачи и не могут быть из него получены.
Проверьте себя, выделив входные данные в задачах:
Вычислить объемы nцилиндров с высотойhи радиусами основанийr,r+3,r+6,r+9, …..
Вычислить S=, где– заданный массив изnэлементов.
В алгоритмевходные данные представляются переменными. Значения их алгоритм запрашивает только в процессе выполненияопераций ввода. Такое разделение алгоритма и данных позволяет описать обработку данных в общем виде, по аналогии с формулой, и тем самым обеспечивает упомянутое выше свойство массовости алгоритма.
Суть операции ввода состоит в преобразовании значений данных из внешнейформы, в которой они задаются пользователем (например, набором на клавиатуре), в форму согласно описанию в программе (внутреннююформу). Необходимость этих специфических операций преобразования формы представления данных объясняется тем, что компьютер (а точнее, процессор) обрабатывает только данные во внутреннем представлении. Для просмотра результатов необходимо записать операции вывода - преобразования результатов из внутреннего представления во внешнее.
Если используется интерактивный режим ввода данных (в диалоге), то для программы значений данных не существует до момента набора их на клавиатуре. По достижении операции ввода программа приостанавливается («прерывание по вводу») и ждет набора данных с клавиатуры. Чтобы не испытывать дискомфорта перед пустым экраном, в программе в режиме диалога предусматриваютприглашения – тексты, которые выводятся перед выполнением операторов вывода.
При вводе из дискового файладанные заранее записываются в файл, откуда и читаются программой. Приглашения здесь не нужны. Для внешнего наблюдателя работа программы не прерывается вплоть до получения результата (или аварийного завершения).