ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 31.03.2021
Просмотров: 6804
Скачиваний: 51
241
ческих) строк. Поэтому в языке Паскаль предусмотрен стандартный файловый тип TEXT (он не
является file of char, скорее всего, это - file of string[n]). Логические строки бывают разной длины,
в том числе и нулевой. В конец каждой строки помещается специальный символ «конец строки»
(eoln - «end of line»). В качестве печатного символа конца строки используют литеру #. Текстовый
файл (text) является строго последовательным, к нему не применимы некоторые встроенные
функции, в частности, seek. В отличие от типизированных файлов, с текстовым файлом нельзя од-
новременно проводить операции чтения (read) и записи (write). Однако, допустимы операторы
writein и readln. Числовые данные, целые и вещественные, в текстовом файле должны записывать-
ся через пробел.
Ниже приведены несколько примеров, иллюстрирующих работу с файлами.
Пример 1.
Вы-
вод данных на печатающее устройство - принтер (1st:).
Программа 23
program print;
var
fal :text;
x :real;
name :
string[25];
begin
assign (fal, ' 1st:'); rewrite (fal); x:2.5; name:"'Слава';
writeln(fal,x:8:2) ;
writeln(fal,'Привет, '.name); close(fal) :
end. (Здесь файловая переменная fal связывается с принтером 1st:, и запись
в файл fal практически означает вывод на печать)
Пример 2.
Создание и сохранение в файле «xxx.dat» последовательности целых чисел от 10
до 20.
Программа 24
program zapis;
var
f: file of integer; i: integer;
begin
assign(f,'xxx.dat'); rewrite(f);
for i:=10 to 20 do write(f,i); close (f);
end. (После выполнения программы формируется внешний файл xxx.dat)
Пример 3.
Считывание первых пяти компонент из существующего файла «xxx.dat» и вывод
на дисплей квадратов
этих значений.
Программа 25
program read;
var ff: file of integer; j,i : integer;
begin
assign(ff,'xxx.dat'); reset(ff) ;
for j:=l to 5 do begin read(ff.i); writeln(i*i);
end;
close(ff);
end.
Пример 4.
В текстовом файле (text) «slov.txt» содержится русский текст. Определить сколь-
ко гласных букв в тексте.
Программа 26
program text;
var
ft : text; n : integer; ch : char; st : set of chart begin
242
assign (ft,'slov.txt'); reset(ft);
st
:=
['A'.'E','И','О','У,'Ы','Э','Ю','Я'];
st := st+['a','e','и','о','у','ы','э','ю','я'];
n: =0;
while not eof(ft) do begin
read(ft, ch); if ch in st then n:=n+l;
end;
close(ft);
writeln; write('кол-во гласных букв =',n);
end.
Поскольку длина текста (файла) неизвестна, то в цикле «пока» используется логическая
функция eof(f), которая возвращает значение TRUE, если найден конец файла.
Пример 5.
Шифрование и дешифрование текста.
Программа шифрования заданного текста (sekret) использует следующее правило шифров-
ки: каждая буква в тексте заменяется на букву, расположенную на n позиций вправо от искомой в
русском алфавите. Причем последним символом алфавита является пробел '', а далее алфавит про-
должается циклически.
Значение смещения n находится во внешнем файле 'n.key', который формируется програм-
мой key. Зашифрованный текст выводится во внешний файл с именем «шифр.eхe» , а также на
дисплей.
Программа дешифровки (retsek) считывает шифрованный текст
из файла «шифр.tхt» и вы-
водит на экран дисплея искомый текст.
Программа 27 (а)
program key;
var
n : integer; f : file of integer;
begin , .
assign (f,'n.key'); rewrite(f); write\('Bвeди ключ(смещение): ');
readln(n);
write(f,n); close(f);
end.
Программа 27 (б)
program sekret;
var
| slovo,anslovo: string[100];
alfavit : string[33];
n, i, k, p : integer;
fkl : file of integer;
fs : text;
begin
alfavit:='абвгдежзийклмнопрстуфхцчшщъыьэюя ';
assign(fkl,'n.key'); reset(fkl); read(fkl,n); close(fkl);
writeln; write('введи текст: ');
readln(slovo); anslovo:='';
for k:=l to length(slovo) do begin for i:=l
to 33 do
if slovo[k]=alfavit[i] then begin p:=i+n;
if p >33 then p:=p mod 33;
anslovo:=anslovo+alfavit[p];
end;
end;
assign(fs,'шифр.txt'); rewrite(fs); write(fs,anslovo);close(fs);
writeln; write(ansiovo) ;
end.
243
Программа 27 (в)
program retsek;
var slovo, anslovo : string[100];
alfavit : string[33];
n, i, k, p : integer;
fi : file of integer;
f : text;
begin alfavit:='абвгдежзийклмнопрстуфхцчшщъыьэюя ';
assign(fi,'n.key'); reset(fi); read(fi.n); close(fi);
assign(f,'шифр.txt'); reset(f); read(f,anslovo); close(f)
slovo:='' ;
for k:=l to length(anslovo) do
begin for i:=l to 33 do
if anslovo[k]=alfavit[i] then
begin p:=i-n; if p < 1 then p:=33-p mod 33;
slovo:=slovo+alfavit[p];
end;
end;
writeln; write('TeKCT шифровки: ',slovo);
end.
Контрольные вопросы и задания
1. Какие проблемы решаются при использовании файлов?
2. Какие операции и функции используются при работе с файлами?
3. Найдите площадь выпуклого четырехугольника со сторонами х, у, z, t и одной
из диагоналей d.
4. Заданы три комплексных числа. Найдите их сумму,
5. Имеется внешний файл записей «lab.zap», содержащий сведения об ученика.' школы.
Файл формируется приведенной ниже программой.
Составьте программу, в которой необходимо сделать следующее:
а) упорядочить файл по признаку «class» в порядке возрастания;
б) упорядочить файл по признаку «god» в порядке убывания;
в) упорядочить файл в алфавитном порядке.
program lab;
type shcoo 1= record
fiо : string[20], class : 1 .. 11; god : integer; pol: char;
end;
var x:array[1..100] ofshcool; n,i:integer; f:file of school;
begin
write ('введите кол-во учеников:'); readln(n); assign(f,'lab.zap'); rewnte(f);
for i:=l to n do with x[i] do
begin \write('введи Ф.И.О.',1,'-ого ученика:'); readln(fio);
write('клacc:'); readln(class);
write('гoд рождения:-'); readln(god); write('пол(M/Ж):-');
readln(pol); write(f,x[i])…;
end; close(f);
end.
6. Задание рассчитано на двух студентов, использующих «электронную почту» на одном
компьютере. Первый студент составляет программу, в которой формирует внешний файл «пись-
мо». Второй студент должен «прочитать» файл и сформировать «ответ».
ПИСЬМО
ОТВЕТ
а) последовательность целых чисел до 100
| квадраты этих чисел;
б) простые числа в интервале от 1 до 200
| сумма этих чисел
3.6. ДИНАМИЧЕСКИЕ ИНФОРМАЦИОННЫЕ СТРУКТУРЫ
244
Динамические переменные и указатели.
До сих мы рассматривали
статические
пере-
менные. Такие переменные автоматически порождаются при входе в тот блок, в котором они опи-
сываются, существуют на протяжении работы всего блока и уничтожаются при выходе их этого
блока.
Обращение к статическим переменным производится по их именам, а тип определяется их
описанием. Вся работа по размещению статических объектов в памяти машины выполняется на
этапе трансляции. Однако использование только статических переменных может вызвать трудно-
сти при составлении эффективной машинной программы. Во многих случаях заранее неизвестен
размер той или иной структуры данных, или структура может изменяться в процессе выполнения
программы. Одна из подобных структур - последовательный файл - уже ранее рассматривалась.
В языке Паскаль предусмотрена возможность использования
динамических
величин. Для
них выделение и очистка памяти происходит не на этапе трансляции, а в ходе выполнения самой
программы. Для работы с динамическими величинами в Паскале предусмотрен специальный тип
значений -
ссылочный.
Этот тип не относится ни к простым, ни к составным. Переменные ссылоч-
ного типа, или
указатели,
являются статическими переменными. Значением переменной ссылоч-
ного типа является адрес ячейки - места в памяти соответствующей динамической величины, Свое
значение ссылочная переменная получает в процессе выполнения программы, в момент появления
соответствующей динамической величины.
Переменные ссылочного типа (указатели) вводятся в употребление обычным путем с по-
мощью их описания в разделе переменных, а их тип, указывающий на тип создаваемых в про-
грамме соответствующих динамических величин, тоже определяется либо путем задания типа в
описании переменных, либо путем указания имени ранее описанного типа.
Значением указателя является адрес ячейки, начиная с которой будет размещена в памяти
соответствующая динамическая величина. Задание ссылочного типа выполняется по схеме
type <имя ссылочного типа> =
^
<имя типа динамической величины>
(значок
^
указывает на то, что величина является динамической).
Например:
type
р =
^
integer;
q =
^
record
х:integer;
у: string [20]
end;
Объявлены два ссылочных типа - р и q. Первый - указатель на целочисленные значения,
второй - на двухполевую запись.
Связь указателя с динамическим объектом можно изобразить следующим образом:
На этой схеме р - имя указателя; звездочкой изображено значение указателя, а стрелка от-
ражает тот факт, что значением указателя является адрес объекта (ссылка на объект), посредством
которого объект и доступен в программе.
В некоторых случаях возникает необходимость в качестве значения указателя принять «пустую»
ссылку, которая не связывает с указателем никакого объекта. Такое значение в Паскале задается служеб-
ным словом nil и принадлежит любому ссылочному типу. Результаты выполнения оператора p:=nil можно
изобразить
следующим образом:
Имея объявленные типы, можно обычным образом описывать переменные этих типов.
Например,
var i: р; zap: q;
Динамические переменные базовых типов можно вводить прямо в разделе «описания пере-
Указываемый объект
*
Р
*
Р
245
менных»:
var i: ^integer;
Описание указателя еще не резервирует память для значения соответствующего динамиче-
ского объекта. Так, каждое вышеприведенное описание выделяет в памяти два байта для записи
адреса * - значения указателя, но никакой величины типа р или q в памяти не образуется и даже
адреса * еще нет.
Для порождения динамического объекта, на который указывает ссылочная переменная i,
сложит стандартная процедура new(i), где new - «новый» - имя процедуры, i - имя указателя, я
Процедура new(i) выполняет две функции:
1) резервирует место в памяти для размещения динамического объекта соответствующего
типа с именем i;
2) указателю i присваивает адрес динамического объекта i.
Однако, узнать адрес динамической переменной с помощью процедуры writeln(i) нельзя.
Динамические объекты размещаются по типу стека в специальной области памяти — так
называемой «куче», свободной от программ и статических переменных. Как уже было отмечено,
символ ^ после имени указателя означает, что речь идет не о значении ссылочной переменной, а о
значении того динамического объекта, на который указывает эта ссылочная переменная. Так, если
в программе имеется описание переменной
var:^integer
то при выполнении процедуры new(i) порождается динамическая переменная типа integer.
Если затем будет выполнен оператор присваивания
i^:= 58
то этой динамической переменной будет присвоено значение 58.
Имя ссылочной переменной с последующим символом
^
называют «переменной с указате-
лем». Именно она синтаксически выполняет роль динамической переменной и может быть ис-
пользована в любых конструкциях языка, где допустимо использование переменных того типа,
что и тип динамической переменной.
Так, ecли j - статическая переменная типа integer, то допустимы операторы присваивания
j:=j+i^2; i^:i^div 3+4; i^sqr(i^) и т.д.
Если ссылочная переменная b указывает на массив
type mas = array[l... 100] of integer, ,
var b:^mas
то в этом случае переменные с указателем могут выглядеть, например, так:
b^[2], b^[k+5]
.
Если в процессе выполнения программы некоторый динамический объект
р^,
созданный в
результате выполнения оператора new(p), становится ненужным, то его можно уничтожить (очи-
стить выделенное ему место в памяти) с помощью стандартной процедуры dispose(p). В результате
выполнения оператора вида dispose(p) динамический объект, на который указывает ссылочная пе-
ременная р, прекращает свое существование, занимаемое им место в памяти становится свобод-
ным, а значение указателя р становится неопределенным (но не равным nil).
Если до вызова процедуры dispose(p) имел пустое значение nil, то это приведет к «зависа-
нию» программы.
Если же до вызова этой процедуры указатель р не был определен,
то это может
привести к
выходу из строя операционной системы.
Значение одного указателя можно присвоить другому указателю того же типа. Можно так-
же указатели одинакового типа сравнивать друг с другом, используя отношения «=» или «<>».
Стандартные процедуры new и dispose позволяют динамически порождать программные
объекты и уничтожать
их, что дает возможность использовать память машины более эффективно.
Связанные списки данных.
Несмотря на богатый набор типов данных в Паскале, н не ис-
черпывает всего практически необходимого для разработки многих классов программ. В частно-
сти, из разнообразных
связанных структур данных
в языке стандартизированы массивы и файлы,
а кроме них могут потребоваться и схожие с ними, но иные структуры. Для них характерны, в ча-
стности, следующие признаки:
а) неопределенное заранее число элементов;
б) необходимость хранения в оперативной
памяти.