- •Введение в конструирование программ
- •Пенза 2006 г.
- •Предисловие
- •1 Обработка информации на компьютере
- •1.1 Модель обработки информации на компьютере
- •1.2 Основные объекты языка программирования
- •1.2.1 Синтаксические элементы языка программирования
- •1.2.2. Значения и типы
- •1.2.3. Константы и переменные
- •1.2.4. Выражения
- •1.2.5. Операторы
- •1.3 Лабораторные задания
- •1.3.1 Логическая разминка
- •1.3.2 Реализовать схемы программ на языке Object Pascal
- •2 Структурное конструирование программ
- •2.1 Простая программа
- •2.2 Консольное приложение
- •2.2.1 Создание, сохранение и загрузка программы
- •2.2.2 Компиляция и выполнение программы
- •2.3 Лабораторные задания
- •2.3.1 Составление простых программ
- •2.3.2 Выполните трассировку и определите результаты работы программы
- •2.3.3 Программирование с использованием управляющих структур
- •2.4 Подпрограммы
- •2.4.1 Глобальные данные
- •2.4.2 Способы передачи параметров
- •2.4.3 Функции
- •2.4.4 Процедуры
- •2.4.5 Значения параметров по умолчанию
- •2.4.6 Перегрузка функций
- •2.4.7. Рекурсивные подпрограммы
- •2.4.8. Передача наименования подпрограммы как параметра
- •2.5 Отладка программ
- •2.6 Лабораторные задания. Подпрограммы
- •2.6.1 Конструирование подпрограмм
- •2.6.2 Разработка рекурсивных подпрограмм
- •2.7. Модули
- •Interface {интерфейс модуля}
- •Implementation {реализация}
- •Initialization {инициализация}
- •3. Структуры данных
- •3.1. Массивы
- •3.1.1. Действия над массивами
- •I, j : byte; { индексы элементов массивов }
- •3.1.2 Передача массивов в качестве параметров
- •3.1.2.1. Формальные параметры как массивы с фиксированными размерами
- •3.1.2.2. Формальные параметры как массивы со «свободными» размерами
- •3.1.2.3. Определение наименьшего/наибольшего значения массива
- •3.1.3 Лабораторные задания
- •3.1.3.1 Одномерные массивы
- •3.1.3.2. Двумерные массивы
- •3.2. Строки
- •3.2.1 Лабораторные задания
- •3.3. Записи
- •3.3.1 Лабораторные задания
- •3.4 Файлы.
- •3.4.1 Основные понятия и операции
- •3.4.2 Типизированные файлы
- •3.4.3 Текстовые файлы
- •3.4.4 Лабораторные задания
- •3.5 Динамические структуры данных. Указатели
- •3.5.1 Основные понятия и определения
- •3.5.2 Процедуры выделения и освобождения памяти
- •3.5.3 Односвязный список
- •3.5.4 Лабораторные задания. Указатели, список
- •3.5.5 Динамические массивы
- •4. Введение в объектно-ориентированное конструирование программ
- •4.1 Основные понятия и определения
- •4.2 Классы и объекты
- •4.2.1 Структура класса
- •4.2.2 Создание и уничтожение объектов
- •4.2.3 Пример. Класс – динамический массив
- •4.2.5 Операции с объектами
- •4.2.5.1 Оператор is
- •4.2.5.2 Оператор as
- •4.2.5.3 Копирование объектов одного класса
- •4.2.6 Свойства
- •4.2.7 Наследование и полиморфизм
- •4.2.8 События
- •4.2.9 Исключительные ситуации
- •4.2.9.1 Операторы try…except
- •4.2.9.2 Операторы try…finally
- •5. Визуальная разработка программ в delphi
- •5.1. Интегрированная среда разработки программ
- •5.1.1 Проект
- •5.2 Конструирование простого приложения
- •5.2.1 Интерфейс Пользователя
- •5.2.2 Визуальное конструирование
- •5.2.3 Реализация методов
- •5.2.4 Обработка исключительных ситуаций
- •5.2.5 Файлы приложения Калькулятор
- •5.3 Компоненты ввода/вывода данных StringGrid и Memo
- •5.3.1 Компонент StringGrid – таблица строк
- •5.3.1 Ввод массива. Компонент StringGrid
- •5.3.3 Компонент Memo – многострочное окно редактирования
- •5.3.4 Ввод массива. Компонент Memo
- •5.4 Немного о графике
- •5.4.1 Свойство Canvas. Построение графика функции
- •5.4.2 Событие OnPaint
- •Список литературы
- •Приложение а. Кратко о Delphi а.1 Свойства проекта
- •А.2 Программный код пустой формы
- •А.3 Главная форма
- •А.3.1 Свойства главной формы
- •А.3.2 События главной формы
- •А.4 Компоненты Delphi
- •Приложение b. Приложение «Калькулятор»
3.1.2.1. Формальные параметры как массивы с фиксированными размерами
В данном примере (рисунок 3.1) для описания типов параметров используется тип Massiv с фиксированной размерностью массива.
Рисунок 3.1 – Передача массива в подпрограмму
3.1.2.2. Формальные параметры как массивы со «свободными» размерами
Существует несколько возможностей передавать массивы в подпрограмму, не указывая их размеры. В языке Object Pascal для этого можно использовать функции low, high и sizeof.
Использование функций low, high и sizeof в консольном приложении требует подключения модуля SysUtils.
Описание размеров фактического массива должно начинаться с 0.
Использование функций low и high для определения размера массива в подпрограмме приведено на рисунке 3.2.
Функции low и high возвращают соответственно наименьшее и наибольшее значение индекса массива.
Рисунок 3.2 – Использование функций low и high
Для лучшего понимания и правильного использования этих функций удалите комментарии в отладочных операторах программы (рисунок 3.2).
Использование функции sizeof для определения размера массива в подпрограмме приведено на рисунке 3.3.
Функция sizeof возвращает размер данных в байтах.
Рисунок 3.3 – Использование функции sizeof
Для лучшего понимания и правильного использования функции sizeof удалите комментарии в отладочных операторах программы (рисунок 3.3).
3.1.2.3. Определение наименьшего/наибольшего значения массива
Рассмотрим процедуру minmax (рисунок 3.4), которая вычисляет минимальное или максимальное значение в одномерном массиве x и определяет номер этого значения в массиве.
Параметры процедуры minmax
Входные:
x – исходный массив,
compare – наименование функции сравнения (получает значение less или more);
Выходные:
minmaxElement – значение минимального/максимального элемента массива,
minmaxNumber – номер минимального/максимального элемента.
Функция сравнения less возвращает значение истина, если значение первого параметра меньше значения второго параметра.
Функция сравнения more возвращает значение истина, если значение первого параметра больше значения второго параметра.
Процедурный тип соответствующий этим функциям имеет вид:
MinMaxFunc = function (first, second: integer):boolean;
Спецификации функций less и more должны содержать ключевое слово far («дальний вызов»). Это указание необходимо компилятору для правильной генерации исполняемой программы.
Пусть в операторе вызова процедуры minmax в качестве наименования функции сравнения передается less.
Параметр minmaxElement будет получать значение элемента массива x[i], если x[i] меньше текущего значения этого параметра.
Таким образом, после завершения цикла сравнений параметр minmaxElement будет иметь значение наименьшего элемента массива, а параметр minmaxNumber – значение номера этого элемента.
Аналогично будет выполняться процедура minmax, если в качестве наименования функции сравнения передается more. В этом случае параметр minmaxElement будет получать значение элемента массива x[i], если x[i] больше текущего значения этого параметра. В результате minmaxElement будет иметь значение наибольшего элемента массива, а параметр minmaxNumber – значение номера этого элемента.
Результаты вызова процедуры minmax приведены на рисунке 3.5.
Рисунок 3.4 – Пример передачи наименования подпрограммы как параметра
Рисунок 3.5 – Результат работы процедуры minmax
Советы профессионала
Проверяйте ситуацию ВЫХОД ЗА ПРЕДЕЛЫ МАССИВА!
Установите автоматическую проверку выхода за пределы массива
В меню Project выберите пункт Options (условия) и в открывшемся окне Project Options (рисунок 3.6) установите галочку для автоматической проверки выхода за пределы массива – Compile/Range checking.
Если в процессе работы программы происходит выход за пределы массива, то выполнение будет прервано и выдано сообщение об ошибке. Таким образом, в процессе отладки программы Вы будете проинформированы о возникновении этой ситуации и сможете устранить ее причину.
Рисунок 3.6 – Установка свойства Range checking для проверки выхода за пределы массива
Пример. Поиск в массиве
Рассмотрим реализацию алгоритма поиска наименьшего номера K элемента массива (A: array[1..N] of integer), значение которого равно заданному X: .
Вариант 1
i:=1;
while (A[ i ]< >X) and (i <= N) do
i:=i+1;
if A[ i ] = X then
K:=i
else
. . . {элемент не найден};
Этот, очевидный на первый взгляд, код содержит фатальную ошибку.
Пусть i = N и A[ i ]< >X – в этом случае условие продолжение цикла истинно. Тогда i = i + 1 = N+1 и при вычислении выражения A[ i ]< >X в заголовке цикла происходит выход за пределы массива – A[ i ] A[N+1]!
Надеюсь, Вы легко исправите заголовок цикла так, чтобы исключить выход за пределы массива.
Вариант 2
Исключим из заголовка цикла проверку A[ i ]< >X. Вместо этого будем использовать логическую переменную Found.
i:=1;
Found := false; // элемент не найден
while (not Found) and (i <= N) do
if A[ i ] = X then
Found := true // элемент найден
else
i:=i+1;
if Found then
K:=i
else
. . . {элемент не найден};
Добавление логической переменной Found сделало код безопасней, но добавило ему сложность – три проверки на один шаг цикла:
1 – i <= N?
2 – (not Found) and (i <= N) = true ?
3 – A[ i ] = X ?
Это, конечно, далеко не лучший вариант поиска!
Вариант 3 – поиск «с барьером»
Увеличим размер массива A на 1 – A: array[1..N+1] of integer;
Присвоим элементу A[N+1] значение X. A[N+1] – это «барьер».
A[N+1] := X;
i:=1;
while (A[ i ]< >X) do //цикл завершается всегда
i:=i+1;
if i <= N then // цикл завершился при i <= N – элемент найден
K:=i
else
. . . {элемент не найден};
Не продолжайте обработку массива после того, как результат получен
Пусть переменная Found принимает значение true, если в массиве есть хотя бы один элемент больше 0, иначе – false
Вариант 1
Found:= false;
for :=1 to N do begin
if A[i]>0 then
Found:= true; // элемент найден, но цикл продолжается!
end;
if Found then
…{элемент найден}
else
…{нет такого элемента в массиве};
Вариант 2
Found:= false;
for :=1 to N do begin
if A[i]>0 then begin
Found:= true; // элемент найден,
break; // выход из цикла!
end;
end;
if Found then
…{элемент найден}
else
…{нет такого элемента в массиве};