- •Предисловие
- •Основы программирования
- •Понятие алгоритма.
- •Алгоритм Евклида.
- •Задача о поездах и мухе
- •Вместо лирического отступления
- •Этапы подготовки задачи для решения на компьютере
- •Примеры разработки алгоритмов
- •Решение квадратного уравнения.
- •Вычисление интегралов
- •Обработка результатов эксперимента
- •Решение системы линейных алгебраических уравнений
- •Введение в язык программирования Pascal
- •Основные элементы языка
- •Переменные. Стандартные типы.
- •Операции отношения
- •Раздел описаний переменных
- •Выражения. Порядок выполнения операций.
- •Константы
- •Комментарии в программе
- •Операторы
- •2.1.7.1. Оператор присваивания
- •2.1.7.2. Операторы ввода/вывода
- •2.1.7.3. Операторы инкремента и декремента
- •Среда разработки Lazarus
- •Русский язык в консольных приложениях
- •Первая программа
- •Открытие существующего проекта
- •Другие способы создания консольных приложений
- •Типовой пустой проект
- •Операции с целыми числами
- •Вместо лирического отступления 2
- •Стандартные функции с целыми аргументами
- •Операции с вещественными числами (тип real).
- •Форматирование вывода
- •Одновременное использование вещественных и целых чисел.
- •Другие стандартные функции с вещественными аргументами
- •Булевы переменные
- •Условные операторы.
- •2.1.22.1 Оператор if …. then
- •2.1.22.2. Оператор if …then ... else
- •Операторы цикла
- •2.1.23.1. Оператор цикла с предусловием
- •2.1.23.2. Оператор цикла с постусловием
- •2.1.23.3. Оператор цикла с параметром.
- •2.1.23.4. Второй вариант оператора цикла с параметром
- •Оператор выбора case
- •Организация простейшего контроля ввода данных.
- •Вычисление сумм сходящихся рядов
- •Реализация некоторых алгоритмов главы 1.
- •Программа решения задачи о поездах и мухе
- •Программа вычисления определенного интеграла
- •Более сложные элементы языка
- •Общая структура Паскаль – программы
- •Процедуры и функции
- •3.1.1.1 Структура процедуры
- •3.1.1.2. Структура функции
- •3.1.1.3 Глобальные и локальные переменные
- •3.1.1.4 Способы передачи параметров
- •3.1.1.5 Процедуры завершения
- •Еще раз о типах данных
- •Классификация типов данных
- •3.2.1.1 Целый тип
- •3.2.1.2. Интервальный тип
- •3.2.1.3. Перечислимый тип
- •3.2.1.4. Множества
- •3.2.1.5. Логический тип
- •3.2.1.6. Вещественный тип
- •3.2.1.7. Указатели
- •Обработка символьной информации в Паскале
- •Символьные и строковые типы данных.
- •3.3.1.1. Тип Char
- •3.3.1.2. Функции для работы с символами
- •3.3.1.3. Тип String
- •3.3.1.4. Строковые процедуры и функции
- •Массивы
- •Динамические массивы
- •Программа решения системы линейных алгебраических уравнений методом Гаусса
- •3.4.1.1. Вариант 1 – с goto
- •3.4.1.2. Вариант 2 – без goto
- •3.4.1.3. Вариант 3 – наилучшая реализация
- •Модули в Паскале
- •Структура модуля
- •Системные модули
- •3.5.2.1. Модуль CRT
- •Файлы
- •Тип данных – запись
- •Файловые типы
- •Процедуры для работы с файлами
- •3.6.3.1. Общие процедуры для работы с файлами всех типов
- •3.6.3.2. Процедуры для работы с текстовыми файлами
- •3.6.3.3. Процедуры для работы с типизированными файлами
- •3.6.3.4. Процедуры для работы с нетипизированными файлами
- •3.6.3.5. Организация контроля ввода/вывода при работе файлами
- •3.6.3.6. Создание простой базы данных с типизированными файлами.
- •Алгоритмы сортировки
- •Обменная сортировка (метод "пузырька")
- •Сортировка выбором
- •Сортировка вставками
- •Метод быстрой сортировки
- •Алгоритмы поиска
- •Поиск в массивах
- •Вставка и удаление элементов в упорядоченном массиве
- •Динамические структуры данных
- •Представление в памяти компьютера динамических структур.
- •Реализация стека с помощью массивов
- •Указатели
- •Стандартные операции с линейными списками
- •Реализация динамических структур линейными списками
- •4.3.6.1. Реализация стека
- •4.3.6.2. Реализация очереди с помощью линейного списка
- •4.3.6.3. Реализация двоичного дерева с помощью линейного списка
- •Сортировка и поиск с помощью двоичного дерева
- •Три источника и три составные части ООП.
- •Классы и объекты.
- •Обращение к членам класса.
- •Инкапсуляция
- •Спецификаторы доступа.
- •Свойства.
- •Наследование
- •Полиморфизм
- •Раннее связывание.
- •Позднее связывание.
- •Конструкторы и деструкторы.
- •Элементы графического интерфейса
- •Различия между консольными и графическими приложениями
- •Визуальное программирование в среде Lazarus
- •Создание графического приложения
- •Форма и ее основные свойства
- •Компоненты
- •Обработчики событий
- •Простейшие компоненты
- •6.3.5.1. Компонент TLabel
- •6.3.5.2. Кнопки TButton, TBitBtn и TSpeedButton
- •6.3.6.1. Компонент TEdit
- •6.3.6.2. Компонент TLabeledEdit
- •6.3.7.1. Компонент TMaskEdit
- •Специальные компоненты для ввода чисел
- •Тестирование и отладка программы
- •Компоненты отображения и выбора данных
- •6.3.10.1. Компонент TMemo
- •6.3.10.2. Компонент TStringGrid
- •6.3.10.3. Компоненты выбора
- •Компонент TListBox
- •Компонент TComboBox
- •Компоненты выбора – переключатели
- •6.3.10.4. Компоненты отображения структурированных данных
- •Компонент TTreeView
- •Компонент TListView
- •Организация меню. Механизм действий - Actions
- •6.3.11.1. Компонент TMainMenu
- •6.3.11.2. Компонент TToolBar
- •6.3.11.3. Компонент TActionList
- •6.3.11.4. Создание приложений с изменяемыми размерами окон
- •Послесловие
- •Литература
- •Алфавитный указатель
3.6 Файлы
____________________________________________________________________
begin
for j:=1 to n do begin
BlockRead(matrix, temp, SizeOf(real)); a[i-1, j-1]:= temp;
end;
BlockRead(matrix, temp, SizeOf(real)); b[i-1]:= temp;
end;
{Преобразование двумерного массива в одномерный} k:=1;
for i:=0 to n-1 do for j:=0 to n-1 do begin
vector[k]:=a[i,j];
k:=k+1;
end;
CloseFile(matrix);
{Вызов процедуры решения системы линейных алгебраических уравнений методом Гаусса} gauss(vector, b, x, n); {освобождение памяти, распределенной для динамических массивов}
a:=nil;
vector:=nil;
x:=nil;
b:=nil;
writeln(UTF8ToConsole('Нажмите любую клавишу')); readkey;
end.
3.6.3.5. Организация контроля ввода/вывода при работе файлами
При работе с файлами часто возникают непредвиденные ситуации, кото-
рые приводят к ошибкам ввода/вывода. Такие ситуации возникают, например,
если указанный файл не существует на диске или диск не готов к работе или файл по каким-либо причинам был запорчен и прочитать данные невозможно и т.п. В таких случаях, если не предусмотреть соответствующих действий, про-
грамма аварийно завершается. Паскаль предоставляет возможность ввести в
программу контроль операций ввода/вывода. Это дает возможность даже если
254
Глава 3 Более сложные элементы языка
____________________________________________________________________
не исправить сразу возникшую ошибку, то хотя бы локализовать ее, вывести какое-то сообщение или предупреждение и продолжить работу с программой.
Для организации контроля за операциями ввода/вывода применяется функция IOResult. Перед вызовом этой функции необходимо отключить ав-
томатический контроль операций ввода/вывода директивой компилятора
{$I-}. Этой директивой программа как бы сообщает компилятору и операци-
онной системе, что контроль последующих операций ввода/вывода она берет на себя. Только после этого функция IOResult становится доступной. После за-
вершения очередной операции ввода/вывода функция возвращает 0, если опе-
рация прошла успешно. В противном случае функция возвращает код ошибки.
Необходимо анализировать значение функции IOResult сразу после вво-
да/вывода. В противном случае функция сбрасывает свое значение в 0. После завершения опасного участка программы, автоматический контроль вво-
да/вывода нужно восстановить директивой компилятора {$I+}.
Рассмотрим пример. Пусть имеется текстовый файл Data.txt. В про-
грамме моделируется ситуация, когда пользователь записывает в файл последо-
вательности целых чисел в их символьном представлении. Затем программа чи-
тает эти числа в переменную целого типа. В первый раз пользователь вводит строку '1234', во второй раз пользователь случайно ввел вместо цифры недо-
пустимый для числа символ, например вводит строку '12#4', т.е. нажал на клавишу с цифрой 3 в верхнем регистре.
program project1; {$mode objfpc}{$H+} uses
CRT, FileUtil, SysUtils; var
F: TextFile; code: word; number:integer;
255
3.6 Файлы
____________________________________________________________________
s:string; begin
AssignFile(F, 'Data.txt');
Rewrite(F);
s:='1234'; Writeln(F, s); s:='12#4'; Writeln(F, s); Reset(F);
while not Eof(F) do begin
{$I-}
Readln(F, number); {$I+}
code:= IOResult; if code<>0 then begin
writeln(UTF8ToConsole('Ошибка преобразования типов, ')); writeln(UTF8ToConsole('код ошибки '), code);
break end;
writeln('number= ', number);
end;
CloseFile(F);
writeln(UTF8ToConsole('Нажмите любую клавишу'));
readkey;
end.
Как видим, первая строка файла прочитана правильно. Выводится значе-
ние целого числа number=1234. При чтении второй строки файла происходит
256
Глава 3 Более сложные элементы языка
____________________________________________________________________
ошибка преобразования строки символов в целое число, о чем программа и со-
общает пользователю.
Для проверки существования файла удобнее пользоваться функцией
FileExists(fname), где fname имя файла – строка символов. В сле-
дующем фрагменте программе проверяется существование файла на диске. Ес-
ли файл существует, он открывается для чтения, в противном случае создается новый пустой файл с тем же именем:
if not FileExists('My_file.txt') then
Rewrite(kol)
else
Reset(kol);
3.6.3.6. Создание простой базы данных с типизированными файлами.
Рассмотрим пример разработки достаточно большой и сложной програм-
мы. При ее написании мы будем использовать все полученные нами знания по языку Паскаль, изложенные в предыдущих главах. В частности, методы работы с типизированными файлами, в которой используются записи сложной струк-
туры, процедуры и функции, контроль операций ввода/вывода. Освоим технику создания и работы с меню. Фактически создается небольшая и простенькая база данных. Чтобы не загромождать текст программы многочисленными проверка-
ми в программу введены процедуры Reset_file, Read_File и Write_File внутри которых и производится контроль правильности опера-
ций ввода/вывода. Структура записи, используемая в программе имеет вид:
Фамилия |
Группа |
Предмет |
Оценка |
|
|
|
|
program Database_Student; {$mode objfpc}{$H+}
257
3.6 Файлы
____________________________________________________________________
uses
CRT, FileUtil, SysUtils, LConvEncoding, LCLType;
type |
|
student = record |
{тип запись} |
fio: string[24]; |
// фамилия |
predmet: string[32]; // предмет gruppa: string[24]; // группа ocenka: integer;
end;
fstud = File of student;
var
fam: string[24]; // фамилия sub: string[32]; // предмет gr: string[24]; // группа
answ: TUTF8Char; // символ для приема ответа пользователя f, v: fstud; {f,v - файловые переменные,
где f - имя основного файла;
v - имя вспомогательного файла} new_student: student;
choice,choose, ocen: integer; {переменные,
предназначенные для выбора режима} fname: string; {строковая переменная, имя файла на диске без расширения}
full_fname: string; {строковая переменная,
полное имя файла на диске с расширением} code_error: integer; // код ошибки ввода/вывода
// опережающее объявление функций и процедур procedure Reset_File( var f: fstud); forward; procedure Read_File(var f: fstud;
var st: student); forward; procedure Write_File(var f: fstud;
var st: student); forward; procedure check_file; forward;
{ ================ Ввод данных ================ } procedure input_data;
begin
with new_student do begin
258
Глава 3 Более сложные элементы языка
____________________________________________________________________
writeln(UTF8ToConsole(' Фамилия ')); readln(fio); writeln(UTF8ToConsole(' Группа ')); readln(gruppa); writeln(UTF8ToConsole(' Предмет ')); readln(predmet); writeln(UTF8ToConsole(' Оценка ')); repeat
{$I-} readln(ocenka); {$I+}
if (IOResult <> 0) or ((ocenka > 5) or (ocenka < 1)) then
begin
writeln(UTF8ToConsole('Введите целое число от 1 до 5')); end;
until (ocenka >= 1) and (ocenka <= 5); end;
end;
{ ================ Создание файла ================ } procedure create_data;
begin check_file; Rewrite(f);
writeln(UTF8ToConsole(' Введите данные ')); repeat
input_data;
Write(f, new_student);
writeln(UTF8ToConsole(' Продолжить?, ответ - д/н (y/n) ')); readln(answ);
{$IFDEF WINDOWS}
answ:= CP866ToUTF8(answ); {$ENDIF}
until (answ='N') or (answ='n') or (answ='н') or (answ= 'Н');
end;
procedure check_file; var
answ: TUTF8char; begin
if FileExists(full_fname) then begin
259
3.6 Файлы
____________________________________________________________________
Assign(f, full_fname); Reset(f);
writeln(UTF8ToConsole('Текущий файл будет уничтожен!!')); writeln(UTF8ToConsole('Чтобы стереть существующий ')); writeln(UTF8ToConsole('файл, нажмите клавишу Esc,')); writeln(UTF8ToConsole('иначе нажмите любую клавишу.')); repeat
answ:= readkey;
if answ= #27 then begin
writeln(UTF8ToConsole('Вы уверены? Нажмите ')); writeln(UTF8ToConsole('еще раз клавишу Esc')); writeln(UTF8ToConsole('Для отмены нажмите ')); writeln(UTF8ToConsole('любую клавишу.')); answ:= readkey;
if answ = #27 then break;
end;
writeln(UTF8ToConsole('Введите другое имя файла')); CloseFile(f);
readln(fname);
Assign(f, fname +' .dat'); break;
until answ = #27; end;
end;
{ ================ Вывод содержимого файла ================ } procedure out_to_screen;
var j: integer; begin
Reset_File(f); ClrScr; GoToXY(1, 5); j:= 0;
writeln(UTF8ToConsole('*фамилия * группа * предмет*оценка *')); wri-
teln('==============================================='); while not Eof(f) do
begin read(f,new_student); j:= j + 1; GoToXY(2, 6 + j);
260
Глава 3 Более сложные элементы языка
____________________________________________________________________
writeln(new_student.fio); GoToXY(15, 6 + j); writeln(new_student.gruppa); GoToXY(28, 6 + j); writeln(new_student.predmet); GoToXY(48, 6 + j); writeln(new_student.ocenka);
end; wri-
teln('==============================================='); writeln(UTF8ToConsole(' Число студентов='),j:2); writeln(UTF8ToConsole('Нажмите любую клавишу ')); readkey;
end;
{ ========= Поиск записей по заданным полям ============ }
procedure select_data; |
|
|
begin |
|
|
repeat |
|
|
Reset_File(f); |
|
|
ClrScr; |
|
|
GoToXY(10, 10); |
|
|
write |
(UTF8ToConsole('Выбор информации по:')); |
|
GoToXY(10, 11); |
|
|
write |
(UTF8ToConsole(' группе |
- 1')); |
GoToXY(10, 12); |
|
|
write |
(UTF8ToConsole(' предмету |
- 2')); |
GoToXY(10, 13); |
|
|
write |
(UTF8ToConsole(' оценке |
- 3')); |
GoToXY(10, 14);
writeln(UTF8ToConsole(' выход из режима - 4')); readln(choice);
ClrScr;
case choice of 1: begin
write(UTF8ToConsole(' Группа -')); readln(gr);
writeln(UTF8ToConsole(' Сведения по группе '), UTF8ToConsole(gr):5);
end; 2: begin
write(UTF8ToConsole(' Предмет -')); readln(sub);
261
3.6 Файлы
____________________________________________________________________
writeln(UTF8ToConsole(' Сведения по предмету '), UTF8ToConsole(sub):15);
end; 3: begin
write(UTF8ToConsole(' Оценка =')); readln(ocen);
writeln(UTF8ToConsole(' Сведения по оценке '), ocen:1);
end;
else exit;
end; { end of case } while not eof(f) do begin
Read_File(f,new_student); case choice of
1:if new_student.gruppa=gr then writeln(new_student.fio:15,
'',new_student.predmet:15,
'',new_student.ocenka:1);
2:if new_student.predmet=sub then writeln(new_student.fio:15,
'',new_student.gruppa:15,
'',new_student.ocenka:1);
3:if new_student.ocenka=ocen then writeln(new_student.fio:15,
'',new_student.predmet:15,
'',new_student.gruppa:5);
end; { end of case } end; { end of while } GoToXY(5, 24);
writeln(UTF8ToConsole('Нажмите любую клавишу ')); readkey;
until choice = 4; end;
{ ======== Восстановление файла под основное имя f ========== } procedure restorefile;
begin CloseFile(f); CloseFile(v); Erase(f); Rewrite(f);
262
Глава 3 Более сложные элементы языка
____________________________________________________________________
Reset(v);
while not Eof(v) do begin
Read_File(v, new_student); Write_File(f, new_student);
end;
CloseFile(f); CloseFile(v); Erase(v);
{удален вспомогательный файл v под внешним именем s.dat} end;
{================ Добавление записей в файл ================}
procedure add_data; begin
Assign(v, 's.dat'); Rewrite(v);
{"s.dat" - имя вспомогательного файла} Reset_File(f);
{копирование содержимого файла f в файл v } while not Eof(f) do
begin
Read_File(f, new_student); Write_File(v, new_student);
end;
writeln(UTF8ToConsole(' Вводите информацию ')); { записи добавляются в конце файла }
repeat input_data;
Write_File(v, new_student);
writeln(UTF8ToConsole(' Продолжить?, ответ - д/н (y/n) ')); readln(answ);
{$IFDEF WINDOWS}
answ:= CP866ToUTF8(answ); {$ENDIF}
until (answ='N') or (answ='n') or (answ='н') or (answ= 'Н');
restorefile;
end;
{================ Удаление записей из файла ================}
procedure delete_data; begin
Assign(v, 's.dat'); Rewrite(v); Reset(f); ClrScr;
263
3.6 Файлы
____________________________________________________________________
GoToXY(10, 10);
writeln(UTF8ToConsole('Удаление информации по:')); GoToXY(10, 11);
writeln(UTF8ToConsole(' группе |
- 1')); |
GoToXY(10, 12); |
|
writeln(UTF8ToConsole(' фамилии |
- 2')); |
GoToXY(10, 13); |
|
writeln(UTF8ToConsole(' предмету |
- 3')); |
GoToXY(10, 14); |
|
writeln(UTF8ToConsole(' оценке |
- 4')); |
GoToXY(10, 15); |
|
writeln(UTF8ToConsole(' выход из режима - 5')); GoToXY(10, 16);
write(UTF8ToConsole(' выбор режима =')); readln(choice);
case choice of 1: begin
write(UTF8ToConsole(' Группа - ')); readln(gr);
end; 2: begin
write(UTF8ToConsole(' Фамилия - ')); readln(fam);
end; 3: begin
write(UTF8ToConsole(' Предмет - ')); readln(sub);
end; 4: begin
write(UTF8ToConsole(' Оценка - ')); readln(ocen);
end;
5: exit; { выход в основную программу } end; { end of case }
{========= поиск записи для удаления =========== } while not Eof(f) do
begin
Read_File(f, new_student);
case choice of
1: if new_student.gruppa<>gr then Write_File(v,new_student);
264
Глава 3 Более сложные элементы языка
____________________________________________________________________
2:if new_student.fio<>fam then Write_File(v,new_student);
3:if new_student.predmet<>sub then Write_File(v,new_student);
4:if new_student.ocenka<>ocen then
Write_File(v,new_student); else
begin
writeln(UTF8ToConsole(' Ошибка при вводе ')); writeln(UTF8ToConsole('Нажмите любую клавишу ')); readkey;
end;
end; { end of case } end; { end of while } restorefile;
end;
{======== процедура открытия файла с контролем операции ======== } procedure Reset_File( var f:fstud);
begin {$I-} Reset(f); {$I+}
code_error:= IOResult; if code_error <> 0 then begin
writeln(UTF8ToConsole('Файл не существует, код ошибки '), code_error);
writeln(UTF8ToConsole('Нажмите любую клавишу')); readkey;
Halt;
end;
end;
{========== процедура чтения с контролем операции ============}
procedure Read_File(var f: fstud; var st: student); begin
{$I-} Read(f, st); {$I+}
code_error:= IOResult; if code_error <> 0 then begin
265
3.6 Файлы
____________________________________________________________________
writeln(UTF8ToConsole('Ошибка чтения, код ошибки '), code_error);
writeln(UTF8ToConsole('Нажмите любую клавишу')); readkey;
Halt;
end;
end;
{========== процедура записи с контролем операции ============}
procedure Write_File(var f: fstud; var st: student); begin
{$I-} Write(f, st); {$I+}
code_error:= IOResult; if code_error <> 0 then begin
writeln(UTF8ToConsole('Ошибка записи в файл, код ошибки '), code_error);
writeln(UTF8ToConsole('Нажмите любую клавишу')); readkey;
Halt;
end;
end;
{ ============== корректировка записей в файле ============== } procedure find_data;
var r: student; begin
Reset_File(f); Assign(v,'s.dat'); Rewrite(v); ClrScr;
GoToXY(10, 9);
writeln(UTF8ToConsole('Укажите ключ (поле) для поиска')); GoToXY(10, 10); writeln(UTF8ToConsole('корректируемой записи - по:')); GoToXY(10, 11);
writeln(UTF8ToConsole(' группе |
- 1')); |
GoToXY(10, 12); |
|
writeln(UTF8ToConsole(' фамилии |
- 2')); |
GoToXY(10, 13); |
|
writeln(UTF8ToConsole(' предмету |
- 3')); |
GoToXY(10, 14); |
|
writeln(UTF8ToConsole(' оценке |
- 4')); |
GoToXY(10, 15); |
|
266
Глава 3 Более сложные элементы языка
____________________________________________________________________
writeln(UTF8ToConsole(' выход из режима - 5')); GoToXY(10, 16);
write(UTF8ToConsole(' выбор режима =')); readln(choice); ClrScr;
GoToXY(10, 9);
writeln(UTF8ToConsole(' Замена информации ')); case choice of { поиск записи }
1: begin
GoToXY(10, 10); write(UTF8ToConsole('группа=')); readln(gr);
input_data; end;
2: begin GoToXY(10, 10);
write(UTF8ToConsole('фамилия=')); readln(fam);
input_data; end;
3: begin GoToXY(10, 10);
write(UTF8ToConsole('предмет=')); readln(sub);
input_data; end;
4: begin GoToXY(10, 10);
write(UTF8ToConsole('оценка=')); readln(ocen);
input_data; end;
5: exit; { выход в основную программу } end; { end of case }
while not Eof(f) do begin
Read_File(f, r); case choice of
1: begin
if gr=r.gruppa then Write_File(v,new_student)
else Write_File(v,r)
end;
267
3.6 Файлы
____________________________________________________________________
2: begin
if fam=r.fio then Write_File(v,new_student)
else Write_File(v,r)
end; 3: begin
if sub=r.predmet then Write_File(v,new_student)
else Write_File(v,r)
end; 4: begin
if ocen=r.ocenka then Write_File(v,new_student)
else Write_File(v,r)
end;
end; { end of case } end; { end of while } restorefile;
end;
{ ============== основная программа ===================}
begin
writeln(UTF8ToConsole('Введите имя файла:')); readln(fname);
{$IFDEF WINDOWS} fname:=CP866ToUTF8(fname); fname:=UTF8ToAnsi(fname);
{$ENDIF}
full_fname:=fname + '.dat'; Assign(f,full_fname); repeat
ClrScr;
{ Формирование меню работы с основным файлом f } GoToXY(10, 7);
writeln(UTF8ToConsole('Выберите нужный режим работы :')); GoToXY(10, 8);
writeln(UTF8ToConsole('Создание файла |
1')); |
GoToXY(10, 9); |
|
writeln(UTF8ToConsole('Вывод содержимого файла |
2')); |
GoToXY(10, 10); |
|
writeln(UTF8ToConsole('Поиск по заданным полям |
3')); |
268
Глава 3 Более сложные элементы языка
____________________________________________________________________
GoToXY(10, 11); |
|
writeln(UTF8ToConsole('Добавление записей в файл |
4')); |
GoToXY(10, 12); |
|
writeln(UTF8ToConsole('Удаление записей из файла |
5')); |
GoToXY(10, 13); |
|
writeln(UTF8ToConsole('Корректировка записей в файле |
6')); |
GoToXY(10, 14); |
|
writeln(UTF8ToConsole('Выход из программы |
7')); |
readln(choose); |
|
case choose of |
|
{choose - значение для выбора режима работы с файлом f }
1:create_data;
2:out_to_screen;
3:select_data;
4:add_data;
5:delete_data;
6:find_data;
end; { end of case } until choose=7;
end.
В этой программе новым для нас является только опережающее объявле-
ние функций и процедур. В Паскале строго соблюдается правило – каждый объект перед использованием должен быть описан. Что касается функций и процедур, то здесь сделаны некоторые "поблажки". Пусть имеются две проце-
дуры, одна из которых вызывает другую.
procedure A (param: integer;)
begin
. . . . .
B(i);
. . . . .
end;
procedure B(param: integer);
begin
. . . . .
269
3.6 Файлы
____________________________________________________________________
end;
При таком расположении и таком описании процедур компилятор выдаст ошибку "Identifier not found "B"". Можно конечно переставить местами эти процедуры, но можно сделать так называемое опережающее описание про-
цедуры таким вот образом:
procedure B(param: integer); forward; procedure A (param: integer;)
begin
. . . . .
B(i);
. . . . .
end;
procedure B(param: integer); begin
. . . . .
end;
Как видим, опережающее описание заключается в том, что объявляется лишь заголовок процедуры В, а тело процедуры заменяется директивой forward. Теперь в процедуре А можно использовать обращение к процедуре
В, поскольку она уже описана, точнее, известны ее формальные параметры, и
компилятор может правильным образом организовать ее вызов.
Рассмотрим другую ситуацию. Предположим, что процедуры А и В вызы-
вают друг друга:
procedure A (param: integer;)
begin
. . . . .
270
Глава 3 Более сложные элементы языка
____________________________________________________________________
B(i);
. . . . .
end;
procedure B(param: integer);
begin
. . . . .
A(i);
. . . . .
end;
Теперь не поможет и перестановка местами процедур, так как они "зацик-
лены" друг на друга. Только использование опережающего объявления проце-
дуры В позволяет разрешить эту проблему.
procedure B(param: integer); forward; procedure A (param: integer;)
begin
. . . . .
B(i);
. . . . .
end;
procedure B(param: integer); begin
. . . . .
A(i);
. . . . .
end;
271