Чтение записи из файла
Рассмотрим программу, демонстрирующую процесс чтения и обработки записей файла. Программа Чтение записей из файла, диалоговое окно которой представлено на рис. 8.4, а текст — в листинге 8.2, открывает файл, сформированный программой Добавление записи в файл, и, в зависимости от того, какой из переключателей все или выбрать — установлен, выводит список медалей, выигранных соответственно представителями всех стран или страны, название которой введено в поле Страна. Для вывода результата чтения из файла используется компонент Memol.
В табл. 8.2 приведены значения свойств компонентов формы.
Так как компонент Memol предназначен только для просмотра информации, то свойству Readonly (только чтение, просмотр) присвоено значение True. Свойство scroiiBars (полосы прокрутки) компонента Memo позволяет задавать отображаемые полосы прокрутки. По умолчанию свойству scroiiBars присвоено значение ssNone, т. е. полосы прокрутки не отображаются. В рассматриваемом примере выводится вертикальная полоса, поэтому свойству ScroiiBars присвоено значение ssVertical.
Таблица 8.2. Значения свойств компонентов
Свойство |
Значение |
||
RadioButton1 . Checked |
True |
||
Label1 .Enabled |
False |
||
ComboBox1 . Enabled |
False |
||
Memo1 . Readonly |
True |
||
Memo1. ScroiiBars |
ssVertical |
||
Для ввода названия страны используется компонент ComboBox1, что позволяет задавать имя не только прямым вводом названия, но и выбором из списка. Список стран нужно сформировать во время создания формы путем присвоения значения свойству items.
Чтобы сразу после запуска программы список выбора страны был недоступен (т. к. выбран переключатель все группы Показать), свойству Enabled компонентов ComboBox1 и Label1 во время создания формы нужно присвоить значение False.
Список ввода-выбора названия страны (ComboBox1) становится доступным в результате выбора во время работы программы переключателя выбрать. Процедура обработки события Onclick на переключателе RadioButton2 делает доступным поле ComboBox1.
![](image/chtenie-zapisi-iz-fajla_2.gif)
Рис. 8.4. Окно программы Чтение записей из файла
Листинг 8.2. Чтение записей из файла
unit rdrec_;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
RadioButton1: TRadioButton; // переключатель Все
RadioButton2: TRadioButton; // переключатель Выбрать
// текст Страна
Button1: TButton;
GroupBox1: TGroupBox;
Label1: TLabe1;
procedure Button1Click(Sender: TObject);
procedure RadioButton2Click(Sender: TObject);
procedure RadioButton1Click(Sender: TObject);
ComboBox1: TComboBox; // комбинированный список
// для ввода названия страны
Memol: TMemo; // поле вывода записей, удовлетворяющих
// условию запроса
private
{ Private declarations } public
{ Public declarations } end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject) ;
type
// тип медали
TKind = (GOLD,SILVER,BRONZE);
// запись файла
TMedal = record
country:string[20]; sport:string[20];
person:string[40]; kind:TKind;
end;
var
f: file of TMedal; // файл записей
rec: TMedal; // запись, прочитанная из файла
n: integer; // кол-во записей, удовлетворяющих запросу
st: string[80];
begin
AssignFile(f,'a:\medals.db');
{$I-}
Reset (f); // открыть файл для чтения
{$I-}
if IOResult <> 0 then begin
ShowMessage('Ошибка открытия файла БД.');
Exit;
end;
// обработка БД
if RadioButton2.Checked then
Memo1.Lines.Add('*** ' + ComboBox1.Text + ' ***'); n := 0;
Memol.Clear; // очистить список поля Memo
while not EOF(f) do begin
read(f, rec); // прочитать запись
if RadioButton1.Checked or
(rec.country = ComboBoxl.Text) then begin
n := n + 1;
st := rec.person+ ', ' + rec.sport;
if RadioButtonl.Checked then
st := st + ', '+ rec.country; case rec.kind of
GOLD: st := st+ ', золото';
SILVER:st := st+ ', серебро';
BRONZE:st := st+ ', бронза';
end;
Memo1.Lines.Add(st); end;
end;
CloseFile(f); if n = 0 then
ShowMessage('В БД нет запрашиваемой информации.');
end;
// переключатель Выбрать
procedure TForm1.RadioButton2Click(Sender: TObject);
begin
Label1.Enabled := True;
ComboBox1.Enabled := True; // теперь поле Страна доступно
ComboBox1.SetFocus; // курсор в поле Страна
end;
// переключатель Все
procedure TForm1.RadioButton1Click(Sender: TObject);
begin
Label1.Enabled := False;
ComboBox1.Enabled := False; // теперь поле Страна не доступно
end;
end.
Процедура TForm1.Button1Click открывает файл и последовательно считывает находящиеся в нем записи. Содержимое записи добавляется в поле Memol, если прочитанная запись удовлетворяет условию запроса, т. е. содержимое поля country совпадает с названием страны, введенным пользователем в поле редактирования компонента ComboBox1, или если выбран переключатель RadioButton1.
Информация в поле Memo добавляется инструкцией Memo1.Lines.Add(st), которая является инструкцией применения метода Add (Добавить) к компоненту Memo1.
Примечание
Понятие "метод" будет подробно рассмотрено далее, в разделе, посвященном объектно-ориентированному программированию. Сейчас только скажем, что метод— это процедура, инструкция вызова которой записывается особым образом с целью показать, что одним из ее параметров является объект.
Динамические переменные
Динамической переменной называется переменная, память для которой выделяется во время работы программы.
Выделение памяти для динамической переменной осуществляется вызовом процедуры new. У процедуры new один параметр — указатель на переменную того типа, память для которой надо выделить. Например, если р является указателем на тип real, то в результате выполнения процедуры new(p); будет выделена память для переменной типа real (создана переменная типа real), и переменная-указатель р будет содержать адрес памяти, выделенной для этой переменной.
У динамической переменной нет имени, поэтому обратиться к ней можно только при помощи указателя.
Процедура, использующая динамические переменные, перед завершением своей работы должна освободить занимаемую этими переменными память или, как говорят программисты, уничтожить динамические переменные". Для освобождения памяти, занимаемой динамической переменной, используется процедура Dispose, которая имеет один параметр — указатель на динамическую переменную.
Например, если р — указатель на динамическую переменную, память для которой выделена инструкцией new(p), то инструкция dispose (р) освобождает занимаемую динамической переменной память.
Следующая процедура (ее текст приведен в листинге 8.3) демонстрирует создание, использование и уничтожение динамических переменных.
Листинг 8.3. Создание, использование и уничтожение динамических переменных
procedure TForm1.Button1Click(Sender: TObject); var
p1,p2,p3: Integer; // указатели на переменные типа integer
begin
// создадим динамические переменные типа integer
// (выделим память для динамических переменных)
New(p1);
New(p2);
New(p3);
р1^ := 5;
р2^ := 3;
р3^ := р1^ + р2^;
ShowMessage('Сумма чисел равна ' + IntToStr(р3^));
// уничтожим динамические переменные
// (освободим память, занимаемую динамическими переменными)
Dispose(p1);
Dispose(р2);
Dispose(р3);
end;
В начале работы процедура создает три динамические переменные. Две переменные, на которые указывают p1 и р2, получают значение в результате выполнения инструкции присваивания. Значение третьей переменной вычисляется как сумма первых двух.
Добавление элемента в список
Добавление элемента в список выполняется путем корректировки указателей. Для того чтобы добавить элемент в упорядоченный список, нужно сначала найти элемент, после которого требуется вставить новый. Затем следует скорректировать указатели. Указатель нового элемента нужно установить на тот элемент, на который указывает элемент, после которого добавляется новый. Указатель элемента, после которого добавляется новый элемент, установить на этот новый элемент (рис. 8.9).
![](image/dobavlenie-jelementa-v-spisok_4.gif)
Рис. 8.9. Добавление элемента в упорядоченный список
![](image/dobavlenie-jelementa-v-spisok_5.gif)
Рис. 8.10. Диалоговое окно программы Упорядоченный динамический список 2
Следующая программа (ее текст приведен в листинге 8.5, а диалоговое окно — на рис. 8.10) формирует список, упорядоченный по полю Фамилия. Данные вводятся в поля редактирования (Edit1 и Edit2) и нажатием кнопки Добавить (Buttoni) добавляются в список таким образом, что список всегда упорядочен по полю Фамилия.
Листинг 8.5. Добавление элементов в упорядоченный список
unit dlist2_;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Button1: TButton;
Button2: TButton;
Label3: TLabel;
Edit1: TEdit;
Edit2: TEdit;
procedure ButtonlClick(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormActivate(Sender: TObject);
private
{ Private declarations } public
{ Public declarations } end;
var
Form1: TForm1;
implementation
($R *.DFM}
type
TPStudent=ATStudent; //указатель на тип TStudent
TStudent = record
f_name:string[20]; // фамилия
l_name:string[20]; // имя
next: TPStudent; // следующий элемент списка
end;
var
head: TPStudent; // начало (голова) списка
// добавить элемент в список
procedure TForm1.Button1Click(Sender: TObject);
var
node: TPStudent; // новый узел списка
curr: TPStudent; // текущий узел списка
pre: TPStudent; // предыдущий, относительно curr, узел
begin
new(node); // создание нового элемента списка
node^.f_name:=Edit1.Text; // фамилия
node^.l_name:=Edit2.Text; // имя
// добавление узла в список
// сначала найдем в списке подходящее место для узла
curr:=head;
pre:=NIL;
{ Внимание!
Если приведенное ниже условие заменить
на (node. f_name>curr". f__name) and (currONIL) ,
то при добавлении первого узла возникает ошибка времени
выполнения, т. к. curr = NIL и, следовательно,
переменной curr. *name нет!
В используемом варианте условия ошибка не возникает, т. к.
сначала проверяется условие (curr о NIL), значение которого
FALSE, и второе условие в этом случае не проверяется.
}
while (curr о NIL) and (node.f_name > curr^.f_name) do
begin
// введенное значение больше текущего pre:= curr;
curr:=curr^.next; // к следующему узлу
end;
if pre = NIL then
begin
// новый узел в начало списка
node^. next: =head; head:=node;
end
else
begin
// новый узел после pre, перед
curr node^.next:=рre^.next;
рrе^.next:=node;
end;
Edit1.text:='';
Edit2.text:='';
Edit1.SetFocus;
end;
// отобразить список
procedure TForm1.Button2Click(Sender: TObject);
var
curr: TPStudent; // текущий элемент списка
n:integer; // длина (кол-во элементов) списка
at:string; // строковое представление списка
begin
n:=0;
st: = '';
curr:=head;
while curr <> NIL
do
begin n:=n+l;
st:=st+curr^.f_name+' '+currA.l_name+#13;
curr:=curr^.next;
end; if n <> 0
then ShowMessage('Список: '+ЦЗ+st)
else ShowMessage('В списке нет элементов.');
end;
// начало работы программы
procedure TForm1.FormActivate(Sender: TObject);
begin
head:=NIL; // список пустой
end;
end.
Процедура TFormi.ButtoniClick создает динамическую переменную-запись, присваивает ее полям значения, соответствующие содержимому полей ввода диалогового окна, находит подходящее место для узла и добавляет этот узел в список, корректируя при этом значение указателя узла next, после которого должен быть помещен новый узел.
![](image/dobavlenie-jelementa-v-spisok_6.gif)
Рис. 8.11. Пример упорядоченного списка, сформированного программой
Вывод списка выполняет процедура TForml.Button2Сlick, которая запускается нажатием кнопки Показать. После запуска программы и ввода нескольких фамилий, например, в такой последовательности: Иванов, Яковлев, Алексеев, петров, список выглядит так, как показано на рис. 8.11.
Типы данных, определяемые программистом
До этого момента в программах использовались стандартные типы данных: integer, Real, Char, string и Boolean. Вместе с тем, язык Delphi позволяет программисту определить свой собственный тип данных, а затем данные этого типа использовать в программе.
Объявляемый программистом новый тип данных базируется на стандартных типах или на типах, созданных программистом ранее. Тип, определенный программистом, может быть отнесен к:
интервальному;
составному типу данных (записи).
Инструкция with
Инструкция with позволяет использовать в тексте программы имена полей без указания имени переменной-записи. В общем виде инструкция with выглядит следующим образом:
with Имя do
begin
( инструкции программы } end;
где:
with — зарезервированное слово языка Delphi, означающее, что далее, до слова end, при обращении к полям записи имя, имя записи можно не указывать.
Например, если в программе объявлена запись
student:record // информация о студенте
f_name: string[30]; // фамилия
l_name: string[20]; // имя
address: string[50]; // адрес
end;
и данные о студенте находятся в полях Edit1, Edit2 и Edit3 диалогового окна, то вместо инструкций
student.f_name := Editl.text;
student.l_name := Edit2.text;
student.address := Edit3.text;
можно записать:
with student do begin
f_name := Edit1.text; f_name := Edit2.text; address := Edit3.text;
end;
Интервальный тип
Интервальный тип является отрезком или частью другого типа, называемого базовым. В качестве базового обычно используют целый тип данных (integer).
При объявлении интервального типа указываются нижняя и верхняя границы интервала, т. е. наименьшее и наибольшее значение, которое может принимать переменная объявляемого типа. В общем виде объявление интервального типа выглядит так:
Тип = НижняяГраница..ВерхняяГраница;
где:
НижняяГраница — наименьшее значение, которое может принимать переменная объявляемого типа;
верхняяГраница — наибольшее значение, которое может принимать переменная объявляемого типа.
Примеры:
TIndex = 0 .. 100; TRusChar = 'А' .. 'я';
В объявлении интервального типа можно использовать именованные константы. В следующем примере в объявлении интервального типа TIndex использована именованная константа HBOUND:
const
HBOUND=100;
type
TIndex=l..HBOUND;
Интервальный тип удобно использовать при объявлении массивов, например, так:
type
TIndex =1 .. 100;
var
tab1 : array[TIndex] of integer; i:TIndex;
Помимо целого типа в качестве базового можно использовать перечисляемый тип, созданный программистом. В следующем фрагменте на основе типа TMonth объявлен интервальный тип TSammer:
type
TMonth = (Jan, Feb, Mar, Apr, May, Jun,
Jul, Aug, Sep, Oct, Nov, Dec);
TSammer = Jun.. Aug;
Объявление записи
Как любой тип, создаваемый программистом, тип "запись" должен быть объявлен в разделе type. В общем виде объявление типа "запись" выглядит так:
Имя = record
Поле_1 : Тип_1; Поле_2 : Тип_2; Поле_К : Тип_К; end;
где:
record — зарезервированное слово языка Delphi, означающее, что далее следует объявление компонентов (полей) записи;
поле_i и тил_i — имя и тип i-го компонента (поля) записи, где i=1, ..., k;
end — зарезервированное слово языка Delphi, означающее, что список полей закончен.
Примеры объявлений:
type
TPerson = record
f_name: string[20];
l_name: string[20];
day: integer;
month: integer;
year: integer;
address: string[50]; end;
TDate = record
day: integer; month: integer; year: integer;
end;
После объявления типа записи можно объявить переменную-запись (или просто запись), например:
var
student : TPerson; birthday : TDate;
Для того чтобы получить доступ к элементу (полю) переменной-записи (записи), нужно указать имя записи и имя поля, разделив их точкой. Например, инструкция
ShowMessage('Имя: ', student.f_name + #13 + 'Адрес: ', student.address);
выводит на экран содержимое полей f_name (имя) и address (адрес) переменной-записи student.
Иногда тип переменной-записи объявляют непосредственно в разделе объявления переменных. В этом случае тип записи указывается сразу за именем переменной, через двоеточие. Например, запись student может быть объявлена в разделе var следующим образом:
student: record
f_name:string[20];
l_name:string[20];
day:integer;
month:integer;
year:integer;
address:string[50];
end;
Перечисляемый тип
Определить перечисляемый тип — это значит перечислить все значения, которые может принимать переменная, относящаяся к данному типу.
В общем виде объявление перечисляемого типа выглядит так:
Тип =( Значение1, Значение2, ... Значение i)
где:
Значение i — символьная константа, определяющая одно из значений, которое может принимать переменная типа Тип.
Примеры:
TDayOfWeek = (MON,TUE,WED,THU,FRI,SAT,SUN);
TColor = (Red,Yellow,Green);
Примечание
Согласно принятому в Delphi соглашению, имена типов должны начинаться с буквы Т (от слова Туре — тип).
После объявления типа можно объявить переменную, относящуюся к этому типу, например:
type
TDayOfWeek = (MON,TUE,WED,THU, FRI,SAT,SUN) ;
var
ThisDay, LastDay: TDayOfWeek;
Помимо указания значений, которые может принимать переменная, описание типа задает, как значения соотносятся друг с другом. Считается, что самый левый элемент списка значений является минимальным, а самый правый — максимальным. Для элементов типа DayOfWeek справедливо:
MON < TUE < WED < THU < FRI < SAT < SUN
Свойство упорядоченности элементов перечисляемого типа позволяет использовать переменные перечисляемого типа в управляющих инструкциях, например, так:
if (Day = SAT) OR (Day = SUN) then
begin
{ действия, если день — суббота или воскресенье }
end;
Приведенную инструкцию можно записать и так:
if Day > FRI then begin
{ действия, если день — суббота или воскресенье }
end;
Очевидно, что программа, написанная с использованием объявленного программистом типа, более наглядна, легче читается и, следовательно, уменьшается вероятность появления ошибки.
Во время компиляции Delphi проверяет соответствие типа переменной типу выражения, которое присваивается переменной. Если тип выражения не может быть приведен к типу переменной, то выводится сообщение об ошибке.
Например, в фрагменте программы
type
TDayOfWeek = (MON, TUE, WED, THU, FRI, SAT, SUN) ;
ThisDay: TDayOfWeek; begin
ThisDay:=1;
if ThisDay = 6 then begin
{ блок инструкций } end;
инструкция ThisDay:= i; ошибочна, т. к. переменная ThisDay принадлежит к определенному программистом перечисляемому типу TDayOfWeek, а константа, значение которой ей присваивается, принадлежит к целому типу (integer). В условии инструкции if тоже ошибка.
Можно утверждать, что объявление перечисляемого типа — это сокращенная форма записи объявления именованных констант. Например, приведенное выше объявление типа TDayOfWeek равносильно следующему объявлению:
const
MON=0; TUE=1; WED=2; THU=3; FRI=4; SAT=5; SUN=6;
Списки
Указатели и динамические переменные позволяют создавать сложные динамические структуры данных, такие как списки и деревья.
Список можно изобразить графически (рис. 8.6).
![](image/spiski_4.gif)
Рис. 8.6. Графическое изображение списка
Каждый элемент списка (узел) представляет собой запись, состоящую из двух частей. Первая часть — информационная. Вторая часть отвечает за связь со следующим и, возможно, с предыдущим элементом списка. Список, в котором обеспечивается связь только со следующим элементом, называется односвязным.
Для того чтобы программа могла использовать список, надо определить тип компонентов списка и переменную-указатель на первый элемент списка. Ниже приведен пример объявления компонента списка студентов:
type
TPStudent = ^TStudent; // указатель на переменную типа TStudent
// описание типа элемента списка
TStudent = record
surname: string[20]; // фамилия
name: string[20];' // имя
group: integer; // номер группы
address: string[60]; // домашний адрес
next: TPStudent; // указатель на следующий элемент списка
end;
var
head: TPStudent; // указатель на первый элемент списка
Добавлять данные можно в начало, в конец или в нужное место списка. Во всех этих случаях необходимо корректировать указатели. На рис. 8.7 изображен процесс добавления элементов в начало списка.
После добавления второго элемента в список head указывает на этот элемент
![](image/spiski_5.gif)
Рис. 8.7. Добавление элементов в список
Следующая программа (ее текст приведен в листинге 8.4) формирует список студентов, добавляя фамилии в начало списка. Данные вводятся в поля редактирования диалогового окна программы (рис. 8.8) и добавляются в список нажатием кнопки Добавить (suttoni).
![](image/spiski_6.gif)
Рис. 8.8. Окно программы Динамический список 1
Листинг 8.4. Добавление элемента в начало динамического списка
unit dlist1_; interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Edit1: TEdit; // фамилия
Edit2: TEdit; // имя
Button1: TButton; // кнопка Добавить
Button2: TButton; // кнопка Показать
procedure ButtonlClick(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations } public
{ Public declarations } end;
var
Form1: TForm1;
implementation
{$R *.DFM)
type
TPStudent=^TStudent; // указатель на тип TStudent
TStudent = record
f_name:string[20]; // фамилия
l_name: string[20]; // имя
next: TPStudent; // следующий элемент списка
end;
var
head: TPStudent; // начало (голова) списка
// добавить элемент в начало списка
procedure TForml.Button1Click(Sender: TObject);
var
curr: TPStudent; // новый элемент списка
begin
new(curr); // выделить память для элемента списка
curr^.f_name := Edit1.Text;
curr^.1_пате := Edit2.Text;
// добавление в начало списка
curr^.next := head; head := curr;
// очистить поля ввода
Edit1.text:=''; Edit2.text: = " ;
end;
// вывести список
procedure TForml.Button2Click(Sender: TObject);
var
curr: TPStudent; // текущий элемент списка
n:integer; // длина (кол-во элементов) списка
st:string; // строковое представление списка
begin n := 0; st := '';
curr := head; // указатель на первый элемент списка
while curr <> NIL do begin
n := n + 1;
st := st + curr^.f_name + ' ' + curr^.1_name
+#13; curr := curr^.next;
// указатель на следующий элемент end;
if n <> 0
then ShowMessage('Список:' + #13 + st)
else ShowMessage('В списке нет элементов.');
end;
end.
Добавление элемента в список выполняет процедура TForm1.Button1Click, которая создает динамическую переменную-запись, присваивает ее полям значения, соответствующие содержимому полей ввода диалогового окна, и корректирует значение указателя head.
Вывод списка выполняет процедура TForm1.Button2Click, которая запускается нажатием кнопки Показать. Для доступа к элементам списка используется указатель curr. Сначала он содержит адрес первого элемента списка. После того как первый элемент списка будет обработан, указателю curr присваивается значение поля next той записи, на которую указывает curr. В результате этого переменная curr содержит адрес второго элемента списка. Таким образом, указатель перемещается по списку. Процесс повторяется до тех пор, пока значение поля next текущего элемента списка (элемента, адрес которого содержит переменная curr) не окажется равно NIL.
Указатели
Обычно переменная хранит некоторые данные. Однако помимо обычных, существуют переменные, которые ссылаются на другие переменные. Такие переменные называются указателями. Указатель — это переменная, значением которой является адрес другой переменной или структуры данных. Графически указатель может быть изображен так, как на рис. 8.5.
![](image/ukazateli_2.gif)
Рис. 8.5. Переменная-указатель
Указатель, как и любая другая переменная программы, должен быть объявлен в разделе объявления переменных. В общем виде объявление указателя выглядит следующим образом:
Имя: ^ Тил;
где:
Тип — тип переменной, на которую указывает переменная-указатель;
значок ^ показывает, что объявляемая переменная является указателем.
Приведем примеры объявления указателей:
p1: ^integer; р2: ^real;
В приведенном примере переменная p1 — это указатель на переменную типа integer, a p2 — указатель на переменную типа real.
Тип переменной, на которую ссылается указатель, называют типом указателя. Например, если в программе объявлен указатель р: ^integer, то говорят: ^р — указатель целого типа" или "р — это указатель на целое".
В начале работы программы переменная-указатель "ни на что не указывает". В этом случае говорят, что значение указателя равно NIL. Зарезервированное слово NIL соответствует значению указателя, который ни на что не указывает.
Идентификатор NIL можно использовать в инструкциях присваивания и в условиях. Например, если переменные pi и р2 объявлены как указатели, то инструкция
p1 := NIL;
устанавливает значение переменной, а инструкция if р2 = NIL then ShowMessage('Указатель р2 не инициализирован!');
проверяет, инициализирован ли указатель р2.
Указателю можно присвоить значение — адрес переменной соответствующего типа (в тексте программы адрес переменной — это имя переменной, перед которым стоит оператор @). Ниже приведена инструкция, после выполнения которой переменная р будет содержать адрес переменной п.
р := @n;
Помимо адреса переменной, указателю можно присвоить значение другого указателя при условии, что они являются указателями на переменную одного типа. Например, если переменные pi и р2 являются указателями типа integer, то в результате выполнения инструкции
p2 := p1;
переменные pi и р2 указывают на одну и ту же переменную.
Указатель можно использовать для доступа к переменной, адрес которой содержит указатель. Например, если р указывает на переменную 1, то в результате выполнения инструкции
р^ : = 5;
значение переменной i будет равно пяти. В приведенном примере значок ^ показывает, что значение пять присваивается переменной, на которую указывает переменная-указатель.
Упорядоченный список
Как правило, списки упорядочены. Порядок следования элементов в списке определяется содержимым одного из полей. Например, список с информацией о людях обычно упорядочен по полю, содержащему фамилии.
Ввод и вывод записей в файл
Записи можно хранить в файле. Для того чтобы программа могла сохранить значение переменной-записи в файле или ввести его из файла, необходимо объявить файл, указав в качестве типа его компонентов тип "запись". Например, инструкции
type
ТРеrson = record
f_riame: string [20] ;
l_name: string[20];
address: string[50]; end; var
f: file of TPerson;
объявляют файл, компонентами которого являются записи типа TPerson.
Процесс работы с файлом записей практически ничем не отличается от процесса работы с обычным файлом. Сначала надо объявить файловую переменную и с помощью процедуры Assign связать эту переменную с конкретным файлом. Затем нужно открыть файл (для чтения, записи или обновления). После этого можно прочитать запись из файла или записать запись в файл.
Запись
В практике программирования довольно часто приходится иметь дело с данными, которые естественным образом состоят из других данных. Например, сведения об учащемся содержат фамилию, имя, отчество, число, месяц и год рождения, домашний адрес и другие данные. Для представления подобной информации в языке Delphi используется структура, которая носит название запись (record).
С одной стороны, запись можно рассматривать как единую структуру, а с другой — как набор отдельных элементов, компонентов. Характерной особенностью записи является то, что составляющие ее компоненты могут быть разного типа. Другая особенность записи состоит в том, что каждый компонент записи имеет имя.
Итак, запись — это структура данных, состоящая из отдельных именованных компонентов разного типа, называемых полями.