
- •Введение в конструирование программ
- •Пенза 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.5.2 Процедуры выделения и освобождения памяти
3.5.2.1 New и Dispose
В этих процедурах размер запрашиваемой и освобождаемой памяти явно не указывается в процедуре и определяется типом данных. Поэтому описание указателя должно быть только такого вида: ^<имя типа данных>.
New(P) – выделить память, размер которой определяется типом данных указателя P. После успешного завершения операции New значением переменной P становится начальный адрес выделенный области памяти.
Выделяемая процедурой New память не инициализируется каким-либо значением.
Dispose(P) – освободить память, начальный адрес, который определяется значением указателя P. Размер освобождаемой памяти определяется типом данных указателя P.
3.5.2.2 GetMem и FreeMem
В этих процедурах размер запрашиваемой и освобождаемой памяти явно указывается в процедуре.
Для определения необходимого размера выделяемой памяти для информации различного типа рекомендуется использовать функцию Sizeof().
GetMem(P, Size) – выделить память размером Size (единовременно не более 65528 байт) и поместить значение начального адреса выделенной области памяти в указатель P.
FreeMem(P, Size) – освободить выделенную память размером Size, начальный адрес которой определяется значением указателя P.
3.5.3 Односвязный список
Списком называется упорядоченная динамическая структура данных, каждый элемент которой содержит данные и ссылку (указатель), связывающую его со следующим элементом (рисунок 3.6).
Рисунок 3.6 – Структура списка
Структура элемента списка может быть объявлена в программе, например, следующим образом:
type
ptrList = ^TList;{ тип указателя связан со структурой элемента списка }
TList = record { структура элемента списка: }
inf : <тип данных>; { информация (данные) }
next: ptrList; { указатель на элемент списка }
end;
Рассмотрим типовые схемы создания, просмотра и удаления списка на примере односвязного списка, структура которого приведена выше.
Создание списка
Схема создания списка (шаг 1 и шаг 2) приведена на рисунке 3.7.
var
p1, p2, pList: ptrList; { p1 – указатель на новый элемент списка }
{ p2 – вспомогательный указатель, в начале = NIL}
{ pList – указатель на начало списка }
begin
p2 := NIL; { список пуст }
<Цикл добавления элементов в список>
begin
New(p1); { выделяем память для элемента списка }
p1^.inf := <данные>; { формируем данные элемента списка }
p1^.next := p2; { "связываем" элементы списка }
p2 := p1; { сохраняем адрес элемента списка в p2 }
end;
pList:= p2; { Список создан. pList – адрес начала списка }
end.
Просмотр списка
var
p1, pList: ptrList; { pList – указатель на начало списка }
begin
p1 := pList;
while p1<> NIL do begin
<.использование данных элемента списка (p1^.inf) >;
p1 := p1^.next; { перемещаем указатель p1 на следующий элемент }
end;
end.
Рисунок 3.7 – Схема создания списка из двух элементов
Удаление списка
var
p1, p2, pList: ptrList; { pList – указатель на начало списка }
begin
p1 := pList;
while p1<> NIL do begin
p2:=p1; { сохраняем адрес элемента списка в p2 }
p1 := p1^.next; { перемещаем указатель p1 на следующий элемент }
dispose(p2); { удаляем элемент списка, адрес которого p2 }
end;
pList:=NIL; { список пуст }
end.
Советы профессионала
Проверяйте указатели перед применением
Проверяйте переменную, на которую указывает указатель, перед ее использованием
Нарисуйте картинку, которая поможет понять логику использования указателя
Удаляйте указатели в списках в правильном порядке. Удаление указателя на первый элемент может сделать невозможным доступ к другим элементам списка!
Устанавливайте указатель в Nil при удалении указателя
Изолируйте работу с указателями в подпрограммах
Ошибка в указателе – чаще всего, это следствие того, что он указывает не туда, куда должен.