Читайте также: |
|
ЧАСТЬ I
ЗАПИСИ
Цель работы:
- освоить правила работы с записями;
- создать модуль подпрограмм работы с записями.
Введение.
Часто в программировании необходимо объединить разнородные, но логически связанные данные. Например, наш домашний адрес состоит из целых чисел: номеров квартиры, дома, почтового индекса, а также из названий: улицы, города, страны. В языке Паскаль для представления разнородных данных служит структурированный тип, называемый записью или комбинированным типом данных.
Записи, как и массивы, используются для описания упорядоченной совокупности величин. Во многом они схожи, но в отличие от массива, где все компоненты должны быть одного и того же типа, записи обычно содержат компоненты различных типов. В случае массива переменная с индексами однозначно определяет требуемый элемент. В записи же механизм выбора иной, - каждому компоненту, называемому полем, присваивается имя, по которому он и определяется.
Объявление данных типа запись таково:
type < имя типа > = record
< имя поля 1>: < имя типа 1>;
…………………..
< имя поля n>: < имя типа n>
end;
Здесь record (запись) и end – служебные слова;
< имя типа > - идентификатор имени типа;
< имя поля > - идентификатор имени поля.
Например
type adres = record
flat, hause: byte;
city, street: string[50];
zip_code:integer
end;
Для того, чтобы обратиться к некоторому полю записи следует написать имя переменной и через точку – имя нужного поля. Например,
Adres.city:=’Ribniza’; adres.hause:= 35; adres.zip_code:= 5555;
Переменные типа запись можно объявлять и в разделе описания переменных, например
var book: record
author, title: string;
year: 1..3000
end;
а так же задавать в виде типизированных констант. Возможно образование массива, компонентами которого являются записи. Допустим, дни рождений студентов Вашей группы можно описать так:
type date = record
month: (january, february, march, april, may, june,
july, august, september, october, november, december);
day: 1..31;
year: integer
end;
birth_day: array[1..25] of date;
var x,y: birth_day;
При обращении к нужному полю необходимо указать имя массива, индекс интересующей записи и имя необходимого поля. Например,
x[3].day:=27; y[13].year:=1993.
Используя оператор присваивания, возможно обращение не только к отдельным полям записи, а в целом ко всей записи. При этом необходимо чтобы слева и справа от оператора были переменные одного типа, к примеру в рассмотренном фрагменте программы можно написать x:=y;
Поскольку на типы компонент записей нет ограничений, поля могут быть массивами, множествами, записями. Например,
type full_name = record
sur_name, name, father_name: string[100]
end;
book = record
author: full_name;
title: string;
year: integer
end;
Обращение к полям записи через составное имя, т.е. имени записи, разделительной точки и имени поля, чрезвычайно громоздко. Для упрощения такого написания в языке Паскаль вводится оператор присоединения with (предлог с), позволяющий значительно сократить обращение к полям записей. Структура его такова:
with < имя переменной типа запись> do <оператор>;
Здесь в операторе, следующим за служебным словом do, можно опустить имя записи и работать только с именем поля. Возможны конструкции с вложением операторов with друг в друга. При этом необходимо быть внимательным, чтобы избежать неоднозначностей.
В качестве иллюстрации, составим программу, с помощью которой можно расположить фамилии студентов Вашей группы в порядке убывания среднего балла, полученного по результатам сдачи зимней экзаменационной сессии.
Программа состоит из трех процедур:
ReadData – формирование исходных данных;
WriteData – вывод результатов;
SortChoice – сортировка фамилий студентов согласно среднего балла.
Подробности работы программы разберите по тексту, используя комментарии. Для простоты представлены данные по трем студентам, сдававшим четыре экзамена. Использовался алгоритм сортировки выбором.
сonst n=3; m=4;
type student_one = record { запись для данных по одному студенту}
fio: string; {поле формирования фамилии и имени студента}
marks: array[1..m] of 2..5; {поле под массив оценок, полученных в сессию}
sb: real {поле для среднего балла }
end;
student_all = array[1..n] of student_one; { массив для формирования данных
по всм студентам Вашей группы }
var group: student_all;
procedure ReadData(var r: student_all); {Процедура ввода данных и вычисления
среднего балла для каждого студента группы}
var i,k,s:byte;
begin
r[1].fio:=’ Иванов Андрей‘; {формирование данных по первому студенту}
r[1].marks[1]:=4; r[1].marks[2]:=5; r[1].marks[3]:=3; r[1].marks[4]:=3;
r[2].fio:=’ Мунтян Светлана‘; { формирование данных по второму студенту }
r[2].marks[1]:=4; r[2].marks[2]:=4; r[2].marks[3]:=5; r[2].marks[4]:=3;
r[3].fio:=’ Бойко Вячеслав‘; { формирование данных по третьему студенту }
r[3].marks[1]:=4; r[3].marks[2]:=5; r[3].marks[3]:=5; r[3].marks[4]:=5;
for i:=1 to n do { вычисление среднего балла для каждого студента}
with r[i] do
begin s:=0;
for k:=1 to m do s:=s+marks[k];
sb:=1.0*s/m
end;
end;
procedure WriteData(r:sstudent_all); {процедура вывода результатов}
var i:byte;
begin
for i:=1 to n do
with r[i] do writeln(fio:20, sb:7:2)
end;
procedure SortChoice(var gr:student_all); {процедура сортировки методом выбора}
var i,k,kmax:byte;
xmax:real;
st:student_one;
begin
for i:=1 to n-1 do { шаг сортировки }
begin kmax:=i; xmax:=gr[i].sb; st:=gr[i];
for k:=i+1 to n do { поиск максимального элемента}
if gr[k].sb > xmax then
begin kmax:=k; xmax:=gr[k].sb; st:= gr[k] end;
gr[kmax]:=gr[i]; gr[i]:=st; {обмен местами максимального и I -элемента}
end
end;
Begin {Основная программа}
ReadData(group); Writeln(‘несортированные данные’); WriteData(group);
SortChoice(group); Writeln(‘несортированные данные’); WriteData(group); Readln
End.
Введите программу и проведите ее отладку и тестирование. Проведите сортировку фамилий по алфавиту, по результатам первого экзамена. Поэкспериментируйте с программой.
Записи с вариантными полями
До сих пор мы использовали записи с фиксированными частями. Они характеризуются строго определенной структурой. Если необходимо иметь различную структуру в зависимости от ситуации - используют записи с вариантами. Их описание имеет следующий вид:
type NameRecord =record
{описание фиксированных частей}
….
{ описание вариантной части}
case < признак- варианта> of
< список констант выбора>: (<список полей-описаний переменных>);
…
< список констант выбора>: (<список полей-описаний переменных>)
end;
Здесь запись состоит из двух частей: обычной фиксированной и вариантной. Вариантная часть записи формируется с помощью служебных слов case и of, между которыми размещается признак-варианта. Признак-варианта включает переменную, называемую полем-признака или полем тега, и через двоеточие тип-признака.
Конструкция вариантной части записи очень напоминает оператор выбора case, однако это так. В частности, в конце выставляется только одно служебное слово end, закрывающее одновременно и запись и её вариантную часть. Поле тега может отсутствовать. Для именования альтернатив записи можно использовать некоторый стандартный или предварительно объявленный порядковый тип.
Вариантная часть может содержать произвольное число альтернатив. Замечательной её особенностью является то, что каждой альтернативе выделяется только одна область памяти. Это дает, например, дополнительные возможности для преобразования типов
type itr = 1..3;
bir = record
case sel: itr of
1: (r: real);
2: (m: array[1..3] of integer);
3: (b: array[0..5] of byte)
end;
Здесь запись bir имеет три варианта, каждый из которых занимает в памяти один и тот же участок из 6 байт.
В записи может быть только одна вариантная часть и она должна быть расположена за всеми фиксированными полями. Но вариантная часть может содержать и другие записи, в том числе с вариантами, причем степень вложенности записей ограничена лишь объемом памяти.
В качестве демонстрационного примера, составим программу для вывода библиографических ссылок. В этом списке могут быть ссылки на книги и на журнальные статьи.
Например,
1. Ахо А.,Хопкрофт Дж., Ульман Дж. Структуры данных и алгоритмы – М.: Вильямс, 2000.-382с.
2. Bayer R.S., Moore J.S. A fast string searching algorithm.- Communication ACM, 20, N10, (1977), 762 – 772
В ссылках вначале записываются авторы и название, а затем для книг и журнальных статей приводится разная информация. Для книг указывается город, издательство и год издания, а для статей – название журнала, том, серия (если она есть у данного журнала), год и страницы, где помещена статья. Используем в данной задаче записи с вариантами. Поля author, title и year составляют фиксированную часть, а оставшаяся информация будет входить в вариативную часть и различается в пределах двух альтернативных определений.
const m_ref=2;
type select = (book, magazine); { тип, задающий две альтернативы}
entry = record { фиксированная часть}
author, title: string[100];
year: 1..2200;
case tag: select of {вариантная часть}
book: (publisher, city: sstring[50];
page:1..10000);
magazine: (mag_name: string[100];
valume, issue:byte;
page_low, page_up:1..10000)
end;
ref_list = array[1..m_ref] of entry;
var x: ref_list;
procedure ReadRef(var rf:ref_list); {процедура ввода данных}
begin
with rf[1] do begin
tag:= book;
author:=’Ахо А.,Хопкрофт Дж., Ульман Дж.’;
title:=’Структуры данных и алглритмы’;
year:=2000;
page:=382;
pablisher:=’Вильямс’;
cyti:= ‘M.:’;
end;
with rf[2] do begin
tag:= magazine;
author:=’Bayer R.S., Moore J.S.’;
title:=’A fast string searching algorithm’;
year:=1977;
mag_name:=’Communication ACM;
valume:= 20;
issue:= 10;
page_low:=762; page_up:=772;
end;
end;
procedure WriteRef(rf:ref_list); { процедура вывода}
var I: integer;
begin
for I:= 1 to m_ref do
with rf[I] do begin
writeln(I:2, auther, ‘ ‘,title,’.’);
if rf[I].tag = book then writeln(‘_’, city, publisher,’.’,year,’.’,page,’c.’)
else writeln(‘_’,mag_name,’,’,volume,’,N’,issue,’,(‘,year,’),’,
page_low,’_’,page_up)
end
end;
Begin { основная программа}
ReadRef(x); WriteRef(x); readln
End.
Дата добавления: 2015-07-19; просмотров: 55 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
БИОЛОГИЧЕСКИЕ ПРЕДСТАВЛЕНИЯ ДРЕВНИХ ГРЕКОВ И РИМЛЯН | | | Организация стеков. |