Файл: Могилев А.В. Информатика.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 31.03.2021

Просмотров: 6804

Скачиваний: 51

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

 

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 


background image

 

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. 

 


background image

 

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. ДИНАМИЧЕСКИЕ ИНФОРМАЦИОННЫЕ СТРУКТУРЫ 

 


background image

 

244 

Динамические  переменные  и  указатели.

  До  сих  мы  рассматривали 

статические

  пере-

менные. Такие переменные автоматически порождаются при входе в тот блок, в котором они опи-
сываются, существуют на  протяжении работы всего блока и  уничтожаются при выходе их этого 
блока. 

Обращение к статическим переменным производится по их именам, а тип определяется их 

описанием.  Вся  работа  по  размещению  статических  объектов  в  памяти  машины  выполняется  на 
этапе трансляции. Однако использование только статических переменных может вызвать трудно-
сти при составлении эффективной машинной программы. Во многих случаях заранее неизвестен 
размер той или иной структуры данных, или структура может изменяться в процессе выполнения 
программы. Одна из подобных структур - последовательный файл - уже ранее рассматривалась. 

В языке Паскаль предусмотрена возможность использования

  динамических

  величин. Для 

них выделение и очистка памяти происходит не на этапе трансляции, а в ходе выполнения самой 
программы. Для работы с динамическими величинами в Паскале предусмотрен специальный тип 
значений - 

ссылочный.

 Этот тип не относится ни к простым, ни к составным. Переменные ссылоч-

ного типа, или 

указатели, 

являются статическими переменными. Значением переменной ссылоч-

ного типа является адрес ячейки - места в памяти соответствующей динамической величины, Свое 
значение ссылочная переменная получает в процессе выполнения программы, в момент появления 
соответствующей динамической величины. 

Переменные  ссылочного  типа  (указатели)  вводятся  в  употребление  обычным  путем  с  по-

мощью  их  описания  в  разделе  переменных,  а  их  тип,  указывающий  на  тип  создаваемых  в  про-
грамме  соответствующих  динамических  величин,  тоже  определяется  либо  путем  задания  типа  в 
описании переменных, либо путем указания имени ранее описанного типа. 

Значением указателя является адрес ячейки, начиная с которой будет размещена в памяти 

соответствующая динамическая величина. Задание ссылочного типа выполняется по схеме  

 
type <имя ссылочного типа> = 

^

 <имя типа динамической величины> 

(значок 

^

 указывает на то, что величина является динамической).  

Например: 

type 

р = 

^

 integer; 

q = 

^

 record  

х:integer; 
у: string [20] 

end; 

Объявлены  два  ссылочных  типа  -  р  и  q.  Первый  -  указатель  на  целочисленные  значения, 

второй - на двухполевую запись. 

Связь указателя с динамическим объектом можно изобразить следующим образом: 
 
 
 
На этой схеме р - имя указателя; звездочкой изображено значение указателя, а стрелка от-

ражает тот факт, что значением указателя является адрес объекта (ссылка на объект), посредством 
которого объект и доступен в программе. 

В  некоторых  случаях  возникает  необходимость  в  качестве  значения  указателя  принять  «пустую» 

ссылку, которая не связывает с указателем никакого объекта. Такое значение в Паскале задается служеб-
ным словом nil и принадлежит любому ссылочному типу. Результаты выполнения оператора p:=nil можно 
изобразить 

следующим образом: 
 
 

 

Имея объявленные типы, можно обычным образом описывать переменные этих типов. 
Например, 

var i: р; zap: q; 

Динамические переменные базовых типов можно вводить прямо в разделе «описания пере-

Указываемый объект 

Р 

Р 


background image

 

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  позволяют  динамически  порождать  программные 

объекты и уничтожать

 

их, что дает возможность использовать память машины более эффективно. 

Связанные списки данных.

 Несмотря на богатый набор типов данных в Паскале, н не ис-

черпывает всего практически необходимого для разработки многих классов программ. В частно-
сти, из разнообразных 

связанных структур данных

 в языке стандартизированы массивы и файлы, 

а кроме них могут потребоваться и схожие с ними, но иные структуры. Для них характерны, в ча-
стности, следующие признаки: 

а) неопределенное заранее число элементов; 
б) необходимость хранения в оперативной

 

памяти.