Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
delphi / песни о паскале.pdf
Скачиваний:
63
Добавлен:
26.03.2016
Размер:
5.16 Mб
Скачать

Глава 50 Неспортивные рекорды (записи)

Кушать подано!

Вообразите себя в гостях за столом, накрытым посудой и вкусностями. Только стол этот накрыт необычно: в одном углу — стопка тарелок, в другом — букет вилок, а там собраны все ножи. Неудобно, однако! Голодных гостей такие мелочи, ясно, не остановят, но согласитесь, — так накрывать не принято.

Или взять ранец со школярским добром: книгами, тетрадями, ручками и карандашами. Что, если нагрузить одного ученика всеми учебниками класса, другого — всеми тетрадями, а третьего — карандашами? Удобно им будет?

Однако ж, мы поступили именно так в одной из программ главы 41. Вспомните сортировку таблицы футбольного чемпионата. Там мы завели два массива: один — для набранных очков, другой — для названий команд. А затем в ходе сортировки меняли местами элементы этих массивов (программа P_41_3). Добавляя в таблицу чемпионата другие сведения о командах (забитые и пропущенные мячи, выигрыши, проигрыши и так далее), нам придётся заводить для них свои массивы. А потом возиться с перестановкой их элементов при сортировке, — тоска!

Нередко мы сталкиваемся с набором разнородных, но логически связанных предметов или данных, как в упомянутых выше случаях. И воспринимаем такие наборы как нечто целое, — это освобождает наш мозг от второстепенных деталей. Вот бы и в программировании найти средство логического соединения разнородных элементов!

Записи

В современных языках такое средство есть. В Паскале оно называется записью, по-английски — RECORD. «Рекорд» — знакомое словцо, не так ли? — оно имеет отношение к спорту. В самом деле, то, что мы называем спортивными рекордами, изначально было лишь записью в журнале регистрации спортивных достижений: кем, когда, где и сколько. Отсюда и пошло слово «рекорд».

Но вернемся к Паскалю. Итак, запись объединяет в единый набор логически связанные, но разнородные данные и дает этому набору имя. Такое объединение обозначают парой ключевых слов RECORD-END и размещают либо в секции объявления типов, либо в секции объявления переменных. Возьмем футбольную команду и соединим её название и набранные ею очки. Объявим для команды тип данных, который так и назовем — Team — «команда». А затем учредим две переменные этого типа, вот как это выглядит.

390

 

 

 

 

 

Глава 50

 

 

 

 

 

Неспортивные рекорды (записи)

 

 

 

 

 

 

 

type

Team = record

{ тип данных «команда» }

 

 

 

Aces

: integer;

{ набранные очки }

 

 

 

Name

: string;

{ название команды }

 

 

 

end;

 

 

 

 

 

var

Team1, Team2 : Team;

{ две переменных типа «команда» }

 

 

 

 

 

 

 

 

Может показаться, что между ключевыми словами RECORD и END объявлены переменные Aces и Name. Так ли это? И да, и нет. Нет, — потому, что в секции TYPE переменные не объявляют. Да, — потому, что внутри переменных Team1 и Team2 (объявленных чуть ниже в секции VAR) действительно «живут» переменные с именами Aces и Name. Только называются они теперь полями переменных Team1 и Team2.

Как получить доступ к этим полям, спрятанным внутри переменных? Надо к имени переменной добавить так называемый квалификатор поля, или проще —

имя этого поля. Вот так присваивают значения полям переменной Team1.

Team1.Aces := 25;

Team2.Name := ’Dinamo’;

Как видите, квалификатор поля отделяют от имени переменной точкой. Поля

— это «кусочки» более сложных переменных (в данном случае переменных Team1 и Team2). Во всем остальном, кроме способа доступа, поля записей ничем не отличаются от обычных переменных.

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

Team2 := Team1; { перенос всех полей из Team1 в Team2 }

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

Второй тайм

Слышен свисток к началу второго тайма, вернемся на футбольное поле, точнее к программе P_41_3, сортирующей команды в порядке занятых ими мест. Сотворим новую версию этой программы P_50_1, заменив два массива (набранных очков и названий команд) одним. План игры на второй тайм таков. Объявим два типа данных: запись и массив записей. Первый из них — запись — будет содержать сведения об отдельной команде.

391

Глава 50 Неспортивные рекорды (записи)

type TTeam = record

 

mAces : integer;

{ набранные очки }

mName : string;

{ названия команд }

end;

 

 

 

Напомню, что для улучшения читаемости программ мы условились начинать названия типов данных с буквы «T». По этой причине тип данных «команда» (Team) стал называться TTeam. Подобное соглашение примем и для полей записей. Чтобы отличить их от прочих переменных, будем начинать имена полей с буквы «m» (от Member — «элемент», «участник»). Поэтому поля названы здесь как mAces и mName.

Второй из объявляемых типов данных — TChamp (Champ — «чемпионат»)

— представляет собой массив футбольных команд.

TChamp = array [1..CSize] of TTeam; { тип для массива команд }

Стало быть, каждый элемент этого типа содержит внутри себя два поля: число mAces и строку mName. Теперь можно объявить и переменную типа TChamp, то есть, массив команд.

var Champ : TChamp; { массив команд }

Доступ к элементам массива Champ осуществляется так.

Champ[i]

– i-й элемент массива, то есть i-я команда (тип TTeam)

Champ[i].mAces

– количество набранных очков i-й командой

Champ[i].mName

– название i-й команды

 

 

После всего сказанного рассмотрим программу P_50_1 в целом.

392

Глава 50 Неспортивные рекорды (записи)

{ P_50_1 – Футбольный чемпионат (версия 2) } const CSize = 4; { количество команд }

 

{ объявление типов }

 

type

TTeam = record

 

 

mAces : integer;

{ набранные очки }

 

mName : string;

{ названия команд }

 

end;

 

 

TChamp = array [1..CSize] of TTeam; { тип для массива команд }

var

Champ : TChamp; { массив команд }

 

{ Процедура "пузырьковой" сортировки команд }

procedure BubbleSort(var arg: TChamp);

var

i, j : Integer;

 

 

begin

t : TTeam; { для временного хранения при обмене }

 

 

 

for i:= 1 to CSize-1 do

{ внешний цикл }

 

for j:= 1 to CSize-i do

{ внутренний цикл }

 

{ если текущий элемент меньше следующего ...}

 

if arg[j].mAces < arg[j+1].mAces then begin

 

{ то меняем местами соседние элементы }

 

t:= arg[j];

 

{ временно запоминаем }

 

arg[j]:= arg[j+1];

{ следующий -> в текущий }

 

arg[j+1]:= t;

{ текущий -> в следующий }

end;

end;

 

 

 

 

 

var i: integer;

 

 

begin

{--- Главная программа ---}

{Вводим названия команд и набранные очки } for i:=1 to CSize do begin

Write('Название команды: '); Readln(Champ[i].mName); Write('Набранные очки: '); Readln(Champ[i].mAces);

end;

BubbleSort(Champ); { сортируем }

{Выводим результаты }

Writeln('Итоги чемпионата:');

Writeln('Место Команда Очки');

for i:=1 to CSize do begin Writeln(i:3,' ':3, Champ[i].mName,

Champ[i].mAces:(20-Length(Champ[i].mName)) );

end;

Readln;

end.

393

Соседние файлы в папке delphi