SHPORA.net :: PDA

Login:
регистрация

Main
FAQ

гуманитарные науки
естественные науки
математические науки
технические науки
Search:
Title: | Body:

Записи и тип.файлы


ОБЪЯВЛЕНИЕ И ИСПОЛЬЗОВАНИЕ ЗАПИСЕЙ



Объявление типа записи



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

Type

TPoint2D = record

X,Y: Real; {координаты точки}

End;

В примере объявлен тип записи TPoint2D. Каждая запись этого типа содержит 2 поля – X и Y – оба вещественного типа.

Расшифруем название типа TPoint2D:

T – общепринятый префикс (приставка) имени типа в Turbo Pascal’е (T – сокращение от Type).

Point – точка.

2D – общепринятая в информатике запись двухмерного пространства (2 direction).

Этот пример показывает, что имя типа записи должно быть смысловым – оно должно говорить само за себя.



Создадим еще один тип записи – на этот раз в записи будем хранить координаты точки на экране в графическом режиме.

Type

TPoint = record

X,Y:Integer; {координаты точки}

End;

В типе TPoint поля X и Y целого типа, потому что координаты точки на экране – это целые числа.

Используя тип записи TPoint определим записи, хранящие информацию о примитивных геометрических фигурах:

Type

TLine = record {Линия}

P1,p2:TPoint; {координаты точек начала и конца линии}

Color: Byte; {цвет линии}

End;

TCircle = record {Окружность}

Center:TPoint; {координаты центра окружности}

R:Integer; {радиус окружности}

Color: Byte; {цвет линии}

End;



Объявление и использование переменных типа записи



Как и переменные любых других типов, переменные типа запись объявляются в разделе Var.

Пример:

Var

P1,p2:TPoint2D; {переменные типа TPoint2D}

X,y:TPoint; {переменные типа TPoint}

L1,L2:TLine; {переменные типа TLine}

C1,C2:TCircle; {переменные типа TCircle}

A:array[1..10] of TLine; {массив из 10 линий}

F: File of TCircle; {типизированный файл окружностей}



Использование переменных типа запись очень похоже на использование массивов. Как и массивы записи нельзя целиком вводить с клавиатуры и выводить на экран – ввод и вывод осуществляется поэлементно (по полям):



Пример: Ввод/вывод массива целых чисел, и ввод/вывод записи TPoint.



Ввод/вывод массива:

Var

A:Array[1..10] of integer;

N,i:Byte

Begin

{ввод массива}

Read(N);

For i:=1 to N do

Read(a[i]);

{вывод массива}

For i:=1 to N do

Write(a[i],’ ‘);

End.



Ввод/вывод записи:

Var

L:TPoint;



Begin

{ввод записи}

Read(L.X); {ввод поля X}

Read(L.Y); {ввод поля Y}



{вывод записи}

Write(L.X,’ ‘);{вывод поля X}

Write(L.Y,’ ‘);{вывод поля Y}

End.





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



Пример:

Вывод элемента массива: Вывод поля записи:

Write(a[i],’ ‘); Write(L.Y,’ ‘);{вывод поля Y}



Если в качестве поля записи используется другая запись (как в типе TLine или TCircle), то при обращении к такому полю сначала указывается имя записи, затем через точку - имя поля этой записи, а затем через вторую точку - имя поля для поля типа запись.

Пример: Введем и выведем запись типа TLine

Var

LL:TLine;

Begin

{Ввод записи}

Read(LL.p1.X); {ввод X координаты первой точки p1}

Read(LL.p1.Y); {ввод Y координаты первой точки p1}

Read(LL.p2.X); {ввод X координаты второй точки p2}

Read(LL.p2.Y); {ввод Y координаты второй точки p2}

Read(LL.Color); {ввод цвета }

{Вывод записи}

Writeln(LL.p1.X); {вывод X координаты первой точки p1}

Writeln (LL.p1.Y); {вывод Y координаты первой точки p1}

Writeln (LL.p2.X); {вывод X координаты второй точки p2}

Writeln (LL.p2.Y); {вывод Y координаты второй точки p2}

Writeln (LL.Color); {вывод цвета }

End.



И здесь есть сходство с массивами, на этот раз с двумерными – для обращением к элементу двумерного массива сначала указывается имя массива, затем, в квадратных скобках, два индекса элемента.

Пример:

Ввод элемента массива: Ввод поля записи:

Read(kk[1,4]); Read(LL.p1.X);



Работа с массивом записей



Если записи объединены в массив, то обращение к каждой из них производится как и к обычному элементу массива (указанием имени массива и индекса в квадратных скобках), а к полям записи – через точку и имя поля.



Пример: Введем с клавиатуры массив окружностей

Var

N: Byte;

A:Array[1..10] of Tcircle;

I:Byte;

begin

Read(n);

For i:=1 to n do

Begin

Read(a[i].Center.X);

Read(a[i].Center.Y);

Read(a[i].R);

Read(a[i].Color);

End;



Работа с файлом записей



Как уже было сказано выше, записи невозможно целиком (не по полям) ввести с клавиатуры и вывести на экран. Зато записи можно целиком писать в типизированный файл записей и читать из него.



Пример 1: Сохраним введенный массив окружностей A (смотри пример выше) в файле с именем “circles.dat”

Var



F:file of TCircle;



Begin



assign(F,'Circles.dat'); {связываем файловую переменную F

с именем файла}

rewrite(f); {открываем файл для записи}

for i:=1 to n do {сохраняем записи в файле}

write(f , a[i]);

close(f); {закрываем файл}





Пример 2: Загрузим массив окружностей A из файла с именем “circles.dat”



assign(F,'Circles.dat'); {связываем файловую переменную F

с именем файла}

reset(f); {открываем файл для чтения}

n:=FileSize(f); {определяем количество записей в файле}

for i:=1 to n do {загружаем записи из файла}

read(f , a[i]);

close(f); {закрываем файл}





Оператор With



Оператор With позволяет упростить обращение к полям записи.

Общий вид оператора следующий: With X do Y;

где X – имя переменной типа запись

Y – любой оператор

В операторе Y при обращении к полям записи X имя X указывать не нужно.



Пример: Выведем A - массив записей типа TCircle на экран (смотри примеры выше)

For i:=1 to n do

With a[i] do

Begin

Write(‘ a[’,i,’].Center.X=’,Center.X); {Вывод поля a[i].Center.X}

Write(‘ a[’,i,’].Center.Y=’,Center.Y); {Вывод поля a[i].Center.Y}

Write(‘ a[’,i,’].R=’, R); {Вывод поля a[i].R}

Write(‘ a[’,i,’].Color=’, Color); {Вывод поля a[i].Color}

End;

Из примера видно, что за счет использования оператора With сокращается и упрощается текст программы – внутри оператора With не нужно писать имя записи “a[i]” перед именами полей записи.



Хранение записей в памяти компьютера



Как вы знаете, все переменные, объявленные в программе, во время работы программы располагаются в оперативной памяти компьютера. Также вы знаете, что Turbo Pascal, накладывает некоторые ограничения на размер каждой из переменных и на суммарный объем занимаемой памяти – в частности любая переменная не может занимать больше чем примерно 64 килобайта памяти, и все глобальные переменные в сумме не могут занимать больше чем все те же 64 килобайта памяти. Чтобы соблюдать эти условия, нужно уметь рассчитывать объем памяти занимаемой любой переменной в отдельности и всеми переменными в сумме. Заметим, что значение размера памяти занимаемой переменной легко узнать при помощи вызова функции sizeof(имя_переменной) или sizeof(имя_типа).

Объем памяти занимаемый одной переменной типа запись рассчитать очень легко, для этого необходимо сложить объемы, занимаемые каждым полем в отдельности. Например, объем занимаемый записью типа TPoint объявленной так

Type

TPoint = record

X,Y:Integer; {координаты точки}

End;

вычисляется так:

sizeof(TPoint) = sizeof(integer)+sizeof(integer) = 2 + 2 = 4 байта

а объем занимаемый записью типа TCircle, объявленной так

Type

TCircle = record {Окружность}

Center:TPoint; {координаты центра окружности}

R:Integer; {радиус окружности}

Color: Byte; {цвет линии}

End;

вычисляется так:

sizeof(TCircle)=sizeof(TPoint)+sizeof(integer)+sizeof(byte) = 4+2+1 =

= 7 байт



Объем памяти, занимаемый массивом записей рассчитать также очень просто – для этого необходимо умножить объем памяти, занимаемый одним элементом (одной записью) на количество элементов в массиве. Например, если массив TArrayCircles объявлен так:

Type

TArrayCircles = array[1..10] of TCircles;

то объем памяти, занимаемой одним массивом этого типа вычисляется так:

sizeof(TArrayCircles) = sizeof( TCircles)*10 = 7 * 10 = 70 байт



Замечание:

Объемы памяти, занимаемые переменными стандартных типов Turbo Pascal составляют:

Byte, ShortInt, Char, Boolean – 1 байт

Word, Integer - 2 байта

LongInt, Single - 4 байта

Real – 6 байт

Double, Comp – 8 байт

Extended – 10 байт

Каждое множество занимает от 1 до 32 байт (в зависимости от диапазона значений элементов множества)

Файлы - в зависимости от типа.



Строки string – с длиной заданной по умолчанию -

Var

s:string;

занимает 256 байт.

С длиной заданной явно –

Var

s1:string[20];

занимает на один байт больше указанного в квадратных скобках. В нашем случае 20+1 = 21 байт.





Вариантные записи



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

а) несколько разных типов записи,

б) вариантную запись.

Каждый из этих вариантов имеет свои плюсы и свои минусы. Но мы не будем их сравнивать, нас интересует лишь КАК реализуется вариант с вариантной записью.

Варинтная запись состоит из двух частей – фиксированной и вариантной. В начале записи размещается фиксированная часть записи – поля, которые присутствуют во всех вариантах. В конце записи находится вариантная часть записи. Вариантная часть начинается со слова case, непосредственно за которым располагается поле-признак. Затем стоит слово of, между которым, и словом end, завершающим запись, перечисляются альтернативные группы полей.

Замечание: При использовании вариантной записи одновременно может быть использована только одна из альтернативных групп.



Рассмотрим объявление и использование вариантных записей на примере:

Разработаем тип вариантной записи для хранения прямоугольников следующих типов:

1. Пустой прямоугольник.

2. Прямоугольник с заливкой.

3. Прямоугольник с размещенным в нем тексте.

Используя этот тип создадим массив, хранящий информацию о разных прямоугольниках, и используя полученный массив выведем прямоугольники на экран.



Сначала создадим тип вариантной записи.

Проанализируем, какие поля необходимы для разных вариантов прямоугольника.

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

Для заполненного прямоугольника необходимо 4 поля для координат углов прямоугольника, поле для хранения цвета рамки, поле для хранения цвета заливки и поле для хранения стиля заливки.

Для прямоугольника с текстом необходимо 4 поля для координат углов прямоугольника, поле для хранения цвета рамки, поле для хранения цвета текста и поле для хранения самого текста.

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

FigureType = {тип фигур}

( FTRect, {пустой прямоугольник}

FTFillRect, {заполненный прямоугольник}

FTTextInRect {текст в прямоугольнике}

);

Для определения полей нашей записи будем использовать тип TColor, который определим так:

TColor = 0..15; {Цвет}

Теперь создадим тип нашей записи:

TRect = record {Запись, хранящая информацию о прямоугольнике}

{Фиксированная часть записи}

Left,Top,Width,Height:Word; {координаты прямоугольника}

ClBorder:TColor; {Цвет рамки}

{Вариантная часть записи}

case fig:FigureType of {тип прямоугольника – поле-признак}

{ниже перечислены три альтернативные группы полей}

FTRect: (); {пустой прямоугольник не имеет

дополнительных полей}

FTFillRect: {заполненный прямоугольник имеет

два дополнительных поля}

( ClFill:TColor; {цвет заполнения}

StyleFill:Byte {стиль заполнения}

);

FTTextInRect: {текст в прямоугольнике имеет

два дополнительных поля}

( ClText:TColor; {цвет текста}

Str:String[20] {текст}

);

end;



Напишем процедуру ввода вариантной записи с клавиатуры.

{Чтение записи Rect типа TRect с клавиатуры}

procedure ReadRect(var Rect:TRect);

var

case_type :Byte; {переменная для выбора типа}

begin

With Rect do

begin

writeln;

writeln;

writeln('Введите информацию о прямоугольнике:');

{Ввод фиксированной части записи}

writeln(' Координаты верхней левой точки:');

write (' X ='); readln(Left);

write (' Y ='); readln(Top);

write (' Ширину='); readln(Width);

write (' Высоту='); readln(Height);

write (' Цвет рамки='); readln(ClBorder);

writeln;

{Ввод вариантной части записи}

writeln('Введите тип прямоугольника:');

writeln(' 1 - пустой прямоугольник');

writeln(' 2 - прямоугольник с заполнением');

writeln(' 3 - прямоугольник с текстом');

readln(case_type); {ввод номера типа}

{в зависимости от типа вводим дополнительные поля}

case case_type of

2: {прямоугольник с заполнением}

begin

fig:=FTFillRect;

write('Введите цвет заливки :'); readln(ClFill);

write('Введите стиль заливки:'); readln(StyleFill);

end;

3: {прямоугольник с текстом}

begin

fig:=FTTextInRect;

write('Введите цвет текста :'); readln(ClText);

write('Введите текст :'); readln(Str);

end;

else {пустой прямоугольник}

fig:=FTRect;

end;{case ... end}

end; {With ... end}

end; {Procedure ... end}



Напишем процедуру вывода прямоугольника на экран:

{Показ на экране прямоугольника, задаваемого записью Rect типа TRect}

procedure ShowRect(Rect:TRect);

begin

With Rect do

begin

{рисуем рамку прямоугольника}

setcolor(ClBorder);

rectangle(Left,Top,Left+Width-1,Top+Height-1);

{в зависимости от типа фигуры выводим дополнительно:}

case fig of

FTFillRect: {заполненный прямоугольник}

begin

{делаем заливку прямоугольника}

setfillstyle(StyleFill,ClFill);

bar(Left+1,Top+1,Left+Width-2,Top+Height-2);

end;

FTTextInRect: {текст в прямоугольнике}

begin

{печатаем текст в прямоугольнике}

setcolor(ClText);

OutTextXY(Left+2,Top+2,Str);

end;

end;{case ... end}

end; {With ... end}

end; {Procedure ... end}



Теперь напишем фрагмент программы с вводом и выводом массива вариантных записей:

var

r: array[1..10] of TRect;

n,i:Integer;

begin

{ввод массива записей прямоугольников}

write('Введите количество прямоугольников n=');

readln(n);

for i:=1 to n do

ReadRect(r[i]);

...

{Включение графического режима}

...

{показ массива прямоугольников}

for i:=1 to n do

ShowRect(r[i]);

...



Хранение вариантных записей в памяти компьютера



Объем памяти, занимаемый вариантной записью можно вычислить по формуле:

sizeof(вариантная_запись) = sizeof(фиксированная_часть) + sizeof(поле-признак) + Max{sizeof(альтернативная_группа1), sizeof(альтернативная_группа2) .. sizeof(альтернативная_группаN)}

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



Для примера рассчитаем объем, занимаемый одной записью типа TRect. Сначала рассчитаем объем, занимамый всеми полями фиксированной части:

sizeof(фиксированная_часть)= sizeof(Word)*4 + sizeof(TColor) =

= 2*4+1 = 9 байт

Рассчитаем объем, занимаемый полем-признаком:

sizeof(поле-признак) = sizeof(FigureType) = 1 байт

Рассчитаем объемы, занимаемые альтернативными группами:

sizeof(альтернативная_группа FTRect) = 0

sizeof(альтернативная_группа FTFillRect) = sizeof(TColor) +

+ sizeof(Byte) = 1+1 = 2 байта

sizeof(альтернативная_группа FTTextInRect) = sizeof(TColor) +

+ sizeof(string[20]) = 1+21 = 22 байта

Максимальный объем среди альтернативных групп – у группы FTTextInRect – 22 байта.

Теперь сведем все объемы в формулу:



sizeof(вариантная_запись) =

= sizeof(фиксированная_часть) + sizeof(поле-признак) +

+ Max{sizeof(альтернативная_группа1),

sizeof(альтернативная_группа2)

...

sizeof(альтернативная_группаN)} =

= 9 + 1 + 22 = 32 байта

ЗАДАНИЕ НА ЛАБОРАТОРНУЮ РАБОТУ





Цель работы:



Изучить работу с массивами и файлами записей.



Общее задание:



Разработать программу, обеспечивающую ввод, хранение, обработку и вывод информации о множестве объектов заданного типа.

Информация о каждом объекте однотипная, хранится в записи. Тип объекта задается вариантом.

Размер множества объектов ограничен 20 экземплярами.

Во время работы программы множество должно хранится в виде списка, с произвольным доступом. Список необходимо реализовать при помощи одномерного массива записей (array[1..20] of Тип_записи).

Между запусками программы множество должно хранится в виде типизированного файла (File of Тип_записи).



Описание пользовательского интерфейса:

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

1. Очистка списка

2. Просмотр списка

3. Просмотр списка по запросу

4. Загрузка данных из файла в список

5. Сохранение данных из списка в файл

6. Добавление записи в список

7. Удаление записи из списка

8. Сортировка списка

9. Выход из программы



Замечание: Пункты выделенные желтым цветом должны быть реализованы в лабораторной работе №7, а пункты выделенные голубым цветом должны быть реализованы в лабораторной работе №8.

Сдавать лабы нужно обязательно ОТДЕЛЬНО.



Тип меню задается вариантом.



Описание модульной структуры:

Программа должна содержать минимум 3 программных модуля:

1. Модуль работы с меню

2. Модуль работы со списком

3. Главный модуль

Можно из главного модуля вынести процедуры ввода/вывода записей и другие процедуры в четвертый модуль.





Задание по вариантам:



Варианты меню:

1. Способ перемещения по меню.

а) Перемещение по пунктам меню осуществляется с помощью навигационных клавиш ( и других);

б) Перемещение по пунктам меню осуществляется с помощью функциональных клавиш (в этом случае каждому пункту соответствует своя собственная функциональная клавиша);

в) Перемещение по пунктам меню осуществляется с помощью буквенных клавиш (для каждой строки клавиша своя).



2. Размещение пунктов меню

а) Вертикальное меню

б) Горизонтальное меню



Задание по вариантам по пользовательскому интерфейсу:

номер варианта Способ перемещения по меню Размещение пунктов меню

1 с помощью навигационных клавиш Вертикальное меню

2 с помощью функциональных клавиш Вертикальное меню

3 с помощью буквенных клавиш Вертикальное меню

4 с помощью навигационных клавиш Горизонтальное меню

5 с помощью функциональных клавиш Горизонтальное меню

6 с помощью буквенных клавиш Горизонтальное меню

7 с помощью навигационных клавиш Вертикальное меню

8 с помощью функциональных клавиш Вертикальное меню

9 с помощью буквенных клавиш Вертикальное меню

10 с помощью навигационных клавиш Горизонтальное меню

11 с помощью функциональных клавиш Горизонтальное меню

12 с помощью буквенных клавиш Горизонтальное меню

13 с помощью навигационных клавиш Вертикальное меню

14 с помощью функциональных клавиш Вертикальное меню

15 с помощью буквенных клавиш Вертикальное меню

16 с помощью навигационных клавиш Горизонтальное меню

17 с помощью функциональных клавиш Горизонтальное меню

18 с помощью буквенных клавиш Горизонтальное меню

19 с помощью навигационных клавиш Вертикальное меню

20 с помощью функциональных клавиш Вертикальное меню

21 с помощью буквенных клавиш Вертикальное меню

22 с помощью навигационных клавиш Горизонтальное меню

23 с помощью функциональных клавиш Горизонтальное меню

24 с помощью буквенных клавиш Горизонтальное меню

25 с помощью навигационных клавиш Горизонтальное меню







Варианты объектов, информацию о которых необходимо хранить в списке:



В каждом варианте задается тип объекта и перечень полей объекта, которые необходимо хранить в записи. Также задается тип запроса, по которому надо выводить часть списка (выводятся лишь те записи, которые удовлетворяют условию запроса):

Номер варианта Название объекта Поля объекта Тип запроса к списку записей

1 Автобус - Номер маршрута

- Количество остановок

- Названия конечных остановок Количество остановок больше 6, но меньше 12

2 Животное - Вид животного

- Место обитания

- Хищное / травоядное

- Количество особей в дикой природе Травоядные

Количество особей менее 10000

3 Фермер - ФИО фермера

- Засеваемая площадь

- Количество работников Засеваемая площадь более 100,

Количество работников более 5

4 Книга - Название книги

- ФИО автора

- Издательство

- Количество страниц Количество страниц более 300,

Издательство “Диалог-МИФИ”

5 Файл - Имя файла

- Время создания

- Дата создания

- Размер файла Размер файла больше 100 Кб,

Дата создания

10 апреля 2001 г.

6 Футболист - ФИО спортсмена

- Название клуба

- Состав (основной / запасной)

- Зарплата Название клуба “Спартак”

Состав основной

7 Трамвай - Номер трамвая

- ФИО водителя

- Номер маршрута

- Год последнего капитального ремонта Номер трамвая “4”

Год кап.ремонта – не позже 1995

8 Жилец - Адрес

- ФИО жильца

- Число членов семьи

- Занимаемая жилая площадь Занимаемая площадь менее 30 кв.метров

Число членов семьи не менее 7

9 Программист - ФИО программиста

- Языки программирования

- Стаж работы Язык программи-рования С++

Стаж работы не менее трех лет

10 Абонент - ФИО абонента

- Адрес

- Телефон

- Количество междугородных разговоров

- Сумма оплаты Сумма оплаты не менее 300 рублей

Количество звонков не более трех

11 Студент - ФИО студента

- Группа

- Средний балл за сессию

- Размер стипендии Средний балл выше 4,5

Стипендия более 150 рублей

12 Мужчина - ФИО мужчины

- Возраст

- Образование

- Среднемесячный доход

- Имеет машину (да/нет) Возраст не старше 30 лет

Среднемесячный доход не меньше 10000 рублей

13 Чемпион - ФИО чемпиона

- Страна

- В каком году был завоеван титул

- Вид спорта Страна “Россия”

Вид спорта – плавание

14 Фирма - Название фирмы

- Вид услуг

- Годовой оборот Вид услуг – торговля

Оборот – не менее 5 млн. рублей

15 Спорт - Вид спорта

- Стоимость одного комплекта инвентаря

- Количество занимающихся Количество занимающихся не менее 100000 человек

Стоимость инвентаря не более 2000 руб.

16 Оружие - Вид оружия

- Фирма-изготовитель

- Страна изготовитель Страна изготовитель – “Россия”

Вид оружия – пулемет

17 Компьютер - Марка компьютера

- Страна-изготовитель

- Фирма-изготовитель

- Себестоимость

- Цена Себестоимость не более 300 долларов

Цена – не менее 700 долларов

18 Завод - Название завода

- Выпускаемая продукция

- Адрес

- Стоимость основных фондов

- Долг перед государством Стоимость основных фондов не более 100 млн. рублей

Долг перед государством не менее 10 млн. рублей

19 Студент - ФИО студента

- Группа

- Число пропусков занятий в год по болезни

- По другим причинам Число пропусков по болезни не менее 10

Группа “ЭВМд-12”

20 Сотрудник - ФИО сотрудника

- Год рождения

- Домашний адрес

- Специальность

- Стаж работы Специальность “Программист”

Стаж – не менее 5 лет

21 Автомобиль - Марка

- Фирма-производитель

- Класс автомобиля

- Год запуска в производство Фирма-производитель “Mersedes”

Год запуска – 2000

22 Сотрудник - ФИО сотрудника

- Подразделение

- Должность

- E-mail

- Объем почты в месяц Должность – “секретарь”

Объем почты – не менее 100 Мб

23 Болезнь

- Вид болезни

- Основные симптомы

- Инкубационный период Основные симптомы – высокая температура

Период – 3 дня

24 Музыкант

- ФИО музыканта

- Жанр

- Музыкальный инструмент

- Музыкальное образование Образование – отсутсвует

Инструмент – барабан

25 Статья - Название статьи

- ФИО автора

- Название журнала

- Номер журнала

- Год издания Номер журнала – не меньше 5

Год издания - 2000



ПРИМЕР ВЫПОЛНЕНИЯ ЛАБОРАТОРНОЙ РАБОТЫ





Задание:



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



Задание по пользовательскому интерфейсу:

- Размещение пунктов меню - вертикальное меню

- Перемещение по пунктам меню осуществляется с помощью навигационных клавиш



Тип объекта, информацию о которых необходимо хранить в списке:

-Человек, медицинская информация о человеке

- Поля объекта:

- фамилия

- имя

- отчество

- год рождения

- группа крови

- рост

- вес



Тип запроса к списку:

– вывести список тех людей, у кого четвертая группа крови, и кто родился не раньше 1970 года.



Модульная структура:

Представленная программа содержит 3 модуля:

- Модуль Menu_Txt (файл Menu_Txt.pas) – работа с меню

- Модуль Info (файл Info.pas)- работа со списком

- Главный модуль (файл LabRec.pas).



Текст программы



Модуль Menu_Txt



Файл Menu_Txt.pas содержит модуль Menu_Txt



{Файл Menu_Txt.pas

Модуль Menu_Txt

Организация меню в текстовом режиме}

unit menu_txt;



interface



type

{пункт меню}

TItemMenu = record

str:string[76]; {строка пункта меню}

x,y:byte; {координаты начала строки внутри окна меню}

res:byte; {значение, возвращаемое при выборе пункта}

end;



{полная информация о меню}

TMenu = record

nItems:Byte; {количество пунктов}

item:array[1..10] of TItemMenu; {пункты меню}

Left,Top:integer; {координаты левого верхнего угла окна меню}

Width,Height:integer; {ширина и высота меню}

clMenu,clText:byte; {цвет меню и цвет текста}

clMarkedItem,clMarkedText:Byte; {цвет выделенного пункта

меню и цвет текста в выделенном пункте}

MarkedItem:byte; {номер выделенного пункта меню}

end;





{Очистка ВСЕГО экрана черным цветом}

procedure BlackScreen;



{создание цветного окна

Left,Top - координаты левого верхнего угла окна

Width - ширина окна

Height - высота окна

BckColor - цвет фона (цвет окна)

}

procedure ColorWindow(Left,Top,Width,Height,BckColor:Byte);



{Меню

озвращаемое значение:

0 - в случае отказа от выбора

menu.item[menu.markedItem].res - в случае выбора пункта меню

}

function MenuVert(var menu:TMenu):byte;



{показ строки текста в текущем активном окне

str - строка

x,y - координаты начала строки

TxtColor - цвет текста

BckColor - цвет фона

ЗАМЕЧАНИЕ: после вывода строки курсор перемещается в начало

выведенной строки

}

procedure ShowText(const str:string; x,y,TxtColor,BckColor:byte);





implementation

uses crt;



const

{константы кодов клавиш}

keyUp = #72; {стрелка вверх}

keyDown = #80; {стрелка вниз}

keyLeft = #75; {стрелка влево}

keyRight = #77; {стрелка вправо}

keyEnd = #79; {клавиша End}

keyHome = #71; {клавиша Home}

keyEnter = #13; {клавиша Enter}

keyEsc = #27; {клавиша Esc}





{Очистка ВСЕГО экрана черным цветом}

procedure BlackScreen;

begin

window(1,1,80,25);

TextBackground(0);

TextColor(7);

clrscr;

end;



{создание цветного окна

Left,Top - координаты левого верхнего угла окна

Width - ширина окна

Height - высота окна

BckColor - цвет фона (цвет окна)

}

procedure ColorWindow(Left,Top,Width,Height,BckColor:Byte);

begin

window(Left,Top,Left+Width-1,Top+Height-1);

TextBackground(BckColor);

clrscr;

end;



{показ строки текста в текущем активном окне

str - строка

x,y - координаты начала строки

TxtColor - цвет текста

BckColor - цвет фона

ЗАМЕЧАНИЕ: после вывода строки курсор перемещается в начало

выведенной строки

}

procedure ShowText(const str:string; x,y,TxtColor,BckColor:byte);

begin

TextBackground(BckColor); {установка цвета фона}

textcolor(txtcolor); {установка цвета текста}

gotoxy(x,y); {перемещаем курсор в позицию начало строки меню}

write(str); {выводим строку меню}

gotoxy(x,y); {перемещаем курсор в позицию начало строки меню}

end;





{Меню

Возвращаемое значение:

0 - в случае отказа от выбора

menu.item[menu.markedItem].res - в случае выбора пункта меню

}

function MenuVert(var menu:TMenu):byte;

var

c:char; {код нажатой клавиши}

i:byte; {счетчик}

begin

with menu do

begin

{готовим окно, в которое будем выводить}

ColorWindow(Left,Top,Width,Height,clMenu);

{выводим все пункты}

for i:=1 to nItems do

ShowText(item[i].str, item[i].x,item[i].y, clText,clMenu);



while true do

begin

ShowText(item[markedItem].str,

item[markedItem].x,item[markedItem].y,

clMarkedText, clMarkedItem);

{ждем нажатия, какой либо клавиши}

c:=readkey;

if c=#0 then c:=readkey;

{выделенный пункт меню делаем того же цвета что и остальные}

ShowText(item[markedItem].str,

item[markedItem].x,item[markedItem].y,

clText,clMenu);

{обработка нажатия клавиши}

case c of

keyUp: dec(markedItem);

keyDown: inc(markedItem);

keyHome: markedItem:=1;

keyEnd: markedItem:=nItems;

keyEnter: begin {нажата клавиша Enter}

MenuVert:=item[markedItem].res; {возвращается из

функции Menu код возврата выделенного

пункта }

exit; {выход из функции}

end;

keyEsc: begin {нажата клавиша Esc}

MenuVert:=0; {возвращается из функции Menu

0 - сообщение о том, что от выбора отказались}

exit; {выход из функции}

end;

end;



{Обработка особых случаев}

if markedItem<1 then markedItem:=nItems;

if markedItem>nItems then markedItem:=1;

end;

end;



end;



begin

end.





Модуль Info



Файл Info.pas содержит модуль Info



{Файл Info.pas

Модуль Info

Работа со списком записей "Медицинская информация"

}

unit Info;



interface



const

maxNInfo = 20; {максимально возможное количество записей в списке}



type

{Запись "Медицинская информация"}

MedicalInfo = record

familia : string[30]; {фамилия}

imja : string[20]; {имя}

otchestvo : string[25]; {отчество}

YearBirth : integer; {год рождения}

GroupBlood: string[5]; {группа крови}

Height : byte; {рост}

Weight : byte; {вес}

end;



{Список записей "Медицинская информация"}

ListOfPerson = record

n:byte; {количество записей в списке}

person:array [1..maxNInfo] of MedicalInfo; {массив записей}

end;





{Очистить список записей list}

procedure Clear ( var list:ListOfPerson);



{Добавить в конец списка list запись person

Возвращается true - если запись была вставлена

false - если запись не была вставлена

}

function AddPerson ( var list:ListOfPerson;

const person:MedicalInfo):boolean;



{Удалить запись номер del из списка list

Возвращается true - если запись была удалена

false - если запись не была удалена

}

function DelPerson ( var list:ListOfPerson;

const del:byte):boolean;



{Сортировка списка записей list}

procedure SortList ( var list:ListOfPerson);



{Сохранение списка записей list в файле с именем filename

Возвращается true - если список сохранен

false - если была ошибка записи в файл

}

function SaveList ( var list:ListOfPerson;

const filename:string):boolean;



{Загрузка списка записей list из файла с именем filename

Возвращается true - если список загружен

false - если была ошибка чтения

}

function LoadList ( var list:ListOfPerson;

const filename:string):boolean;







implementation





{Очистить список записей list}

procedure Clear(var list:ListOfPerson);

begin

list.n:=0;

end;



{Перестановка в списке list элементов с индексами i и j}

procedure Exchange(var list:ListOfPerson; const i,j:byte);

var

tmp:MedicalInfo;

begin

if i<>j then

begin

tmp := list.person[i];

list.person[i] := list.person[j];

list.person[j] := tmp;

end;

end;



{Добавить в конец списка list запись person

Возвращается true - если запись была вставлена

false - если запись не была вставлена

}

function AddPerson(var list:ListOfPerson;

const person:MedicalInfo):boolean;

begin

if list.n=maxNInfo then

AddPerson:=false

else

begin

inc(list.n);

list.person[list.n]:=person;

AddPerson:=true;

end;

end;





{Удалить запись номер del из списка list

Возвращается true - если запись была удалена

false - если запись не была удалена

}

function DelPerson(var list:ListOfPerson;

const del:byte):boolean;

begin

if (del<1) or (del>list.n) then

DelPerson:=false

else

begin

list.person[del]:=list.person[list.n];

dec(list.n);

DelPerson:=true;

end;

end;



{Сортировка списка записей list}

procedure SortList(var list:ListOfPerson);

var

imin:byte;

i,j:byte;

begin



with list do

begin

if list.n<2 then exit;

for i:=1 to n-1 do

begin

imin:=i;

for j:=i+1 to n do

if person[j].familia<person[imin].familia

then

imin:=j;

Exchange(list,i,imin);

end;

end;

end;



{Сохранение списка записей list в файле с именем filename

Возвращается true - если список сохранен

false - если была ошибка записи в файл

}

function SaveList(var list:ListOfPerson; const filename:string):boolean;

var

f:file of MedicalInfo;

i:byte;

begin

assign(f,filename);

{$I-}

rewrite(f);

{$I+}

if ioresult<>0

then

begin

SaveList:=false;

exit;

end;



for i:=1 to list.n do

write(f,list.person[i]);

close(f);

SaveList:=true;

end;



{Загрузка списка записей list из файла с именем filename

Возвращается true - если список загружен

false - если была ошибка чтения

}

function LoadList(var list:ListOfPerson; const filename:string):boolean;

var

f:file of MedicalInfo;

n,i:byte;

begin

assign(f,filename);

{$I-}

reset(f);

{$I+}

if ioresult<>0

then

begin

LoadList:=false;

exit;

end;



n:=FileSize(f);

if (n<0) or (n>maxNInfo)

then

begin

close(f);

LoadList:=false;

exit;

end;



Clear(list);

for i:=1 to n do

read(f,list.person[i]);

close(f);

list.n:=n;

LoadList:=true;

end;



begin

end.





Главный модуль



Файл LabRec.pas содержит главный модуль - тело программы.



{Файл LabRec.pas



Дисциплина "Программирование на языке высокого уровня"



Лабораторная работа

тема "Обработка записей"

Образец программы



Программа обеспечивает работу с записями "Медицинская

информация",

содержащими следующие поля

1. Фамилия

2. Имя

3. Отчество

4. Год рождения

5. Группа крови

6. Рост

7. Вес



Записи хранятся в списке. Список реализован через массив.

В программе предусмотрены следующие операции над списком

записей:

- Очистка массива записей

- Добавление записи в конец массива

- Удаление записи по номеру

- Сортировка записей по фамилии

- Вывод массива записей на экран

- Вывод на экран части списка

- Сохранение массива записей в файле

- Загрузка массива записей из файла

}



uses crt,menu_txt,info; {в программе кроме стандартного модуля Crt

используются наши собственные модули Menu_Txt и Info}



const

{Главное меню программы}

MainMenu: TMenu=( nItems:9; {количество пунктов}



item:( {пункты меню}

(str:' Очистка массива записей '; x:2; y:2; res:1), {1-й пункт}

(str:' Добавление записи в конец массива '; x:2; y:3; res:2), {2-й

пункт}

(str:' Удаление записи по номеру '; x:2; y:4; res:3), {3-й пункт}

(str:' Сортировка записей по фамилии '; x:2; y:5; res:4), {4-й

пункт}

(str:' Вывод массива записей на экран '; x:2; y:6; res:5), {5-й пункт}

(str:' Вывод на экран части списка '; x:2; y:7; res:8), {6-й пункт}

(str:' Сохранение массива записей в файле '; x:2; y:8; res:6), {7-й

пункт}

(str:' Загрузка массива записей из файла '; x:2; y:9; res:7), {8-й

пункт}

(str:' Выход из программы '; x:2; y:10; res:100), {9-й пункт}

(str:''; x:0; y:0; res:0) {10-й пункт}

);



Left:20; Top:5; {координаты меню}

Width:40; Height:11; {размеры окна меню}

clMenu:2; clText:14; {цвет меню и цвет текста меню}

clMarkedItem:4; clMarkedText:15; {цвет выделенного

пункта}

MarkedItem:1 {номер выделенного пункта}

);



var

persons: ListOfPerson; {список записей}



{очистка списка}

procedure ClearArray;

begin

Clear(persons);

ColorWindow(20,1,40,3,1);

ShowText('Массив очищен!',13,2,14,1);

readkey;

end;



{Вставка записи в массив записей}

procedure InsertToArray;

var

person:MedicalInfo; {вводимая запись}

begin

{вывод приглашения}

ColorWindow(1,16,80,10,3);

ShowText('Введите поля записи:',20,1,14,3);



ShowText('Фамилия : ',3,3,15,3);

ShowText('Имя : ',3,4,15,3);

ShowText('Отчество : ',3,5,15,3);

ShowText('Год рождения : ',3,6,15,3);

ShowText('Группа крови : ',3,7,15,3);

ShowText('Рост : ',3,8,15,3);

ShowText('Вес : ',3,9,15,3);

{ввод всех полей}

gotoxy(20,3);

readln(person.familia);

gotoxy(20,4);

readln(person.imja);

gotoxy(20,5);

readln(person.otchestvo);

gotoxy(20,6);

readln(person.yearbirth);

gotoxy(20,7);

readln(person.groupblood);

gotoxy(20,8);

readln(person.Height);

gotoxy(20,9);

readln(person.Weight);



if AddPerson(persons,person) {дабавляем запись в список}

then

begin {если запись добавлена}

ColorWindow(20,1,40,3,1);

ShowText('Запись в массив добавлена!',6,2,14,1);

end

else

begin {если запись не добавлена}

ColorWindow(20,1,40,3,4);

ShowText('Массив полон - добавлять некуда!',3,2,15,1);

end;

readkey;

end;



{Удалить запись из массива}

procedure DeleteFromArray;

var

del:byte; {индекс удаляемого элемента массива}

begin

{вывод приглашения}

ColorWindow(1,16,80,10,3);

ShowText('Введите индекс удаляемой записи:',10,3,14,3);



gotoxy(45,3);

readln(del);



if DelPerson(persons,del)

then

begin {если запись удалена}

ColorWindow(20,1,40,3,1);

ShowText('Запись из массива удалена!',6,2,14,1);

end

else

begin {если запись не удалена}

ColorWindow(15,1,50,3,4);

ShowText('Неверный индекс записи - запись не удалена!',3,2,15,4);

end;

readkey;

end;



{Сортировка записей в списке по фамилиям}

procedure SortArray;

begin

SortList(persons);

ColorWindow(20,1,40,3,1);

ShowText('Массив отсортирован!',13,2,14,1);

readkey;

end;



{Просмотр массива}

procedure ViewArray;

var

i:byte;{счетчик}

begin

BlackScreen;

ColorWindow(1,1,80,23,1);

{вывод шапки}

gotoxy(1,1);

write('|Фамилия |Имя |Отчество |',

'Год_рождения|Группа_крови|Рост|Вес');

gotoxy(1,2);

write('+-----------------+--------------+-----------+',

'------------+------------+----+---');



{вывод всех записей}

for i:=1 to persons.n do

begin

gotoxy(1,i+2);

write('|',persons.person[i].familia);

gotoxy(19,i+2);

write('|',persons.person[i].imja );

gotoxy(34,i+2);

write('|',persons.person[i].otchestvo );

gotoxy(46,i+2);

write('|',persons.person[i].YearBirth );

gotoxy(59,i+2);

write('|',persons.person[i].GroupBlood );

gotoxy(72,i+2);

write('|',persons.person[i].Height);

gotoxy(77,i+2);

write('|',persons.person[i].Weight);

end;



ShowText('Нажмите любую клавишу для продолжения работы!',15,23,15,4);

readkey;

end;



{Просмотр части массива - показ только тех людей,

кто родился не раньше 1970 года

и имеет 4 группу крови

}

procedure ViewPartArray;

var

i:byte;{счетчик}

begin

BlackScreen;

ColorWindow(1,1,80,23,1);

{вывод шапки}

ShowText('Список людей, имеющих 4 группу крови, '+

'родившихся не раньше 1970 года',5,1,14,1);

textcolor(15);

gotoxy(1,2);

write('|Фамилия |Имя |Отчество |Год_рождения|');

gotoxy(1,3);

write('+-----------------+--------------+-----------+------------+');



{просмотр всех записей}

for i:=1 to persons.n do

with persons.person[i] do

if (YearBirth>=1970) and (GroupBlood='4') {вывод лишь тех записей}

then {год рождения у которых <=1970, а группа крови =4}

begin

gotoxy(1,i+3);

write('|',familia);

gotoxy(19,i+3);

write('|',imja );

gotoxy(34,i+3);

write('|',otchestvo );

gotoxy(46,i+3);

write('|',YearBirth );

end;



ShowText('Нажмите любую клавишу для продолжения работы!',15,23,15,4);

readkey;

end;



{сохранение списка в файле}

procedure SaveArray;

var

filename: string;{имя файла}

begin

{ввод имени файла}

ColorWindow(1,16,80,10,3);

ShowText('Введите имя файла для записи массива:',10,3,14,3);

gotoxy(50,3);

readln(filename);



if SaveList(persons,filename) {сохранение}

then

begin {если список сохранен в файле}

ColorWindow(20,1,40,3,1);

ShowText('Массив сохранен в файле '+filename,2,2,14,1);

end

else

begin {если была ошибка сохранения}

ColorWindow(15,1,50,3,4);

ShowText('Ошибка записи в файл '+filename,3,2,15,4);

end;



readkey;

end;





{загрузка списка из файла}

procedure LoadArray;

var

filename: string;

begin

{ввод имени файла}

ColorWindow(1,16,80,10,3);

ShowText('Введите имя файла для чтения массива:',10,3,14,3);

gotoxy(50,3);

readln(filename);



if LoadList(persons,filename) {загрузка}

then

begin {если список загружен}

ColorWindow(20,1,40,3,1);

ShowText('Массив загружен из файла '+filename,2,2,14,1);

end

else

begin {если список не загружен}

ColorWindow(15,1,50,3,4);

ShowText('Ошибка при чтении из файла '+filename,3,2,15,4);

end;



readkey;

end;





{Тело программы}



begin



Clear(persons); {инициализация списка - очистка}

repeat

BlackScreen; {очистка экрана}



case MenuVert(MainMenu) of {Вызываем меню

и в зависимости от выбранного пункта выполняем

соответствующее действие}

1: ClearArray;

2: InsertToArray;

3: DeleteFromArray;

4: SortArray;

5: ViewArray;

6: SaveArray;

7: LoadArray;

8: ViewPartArray;

0,100: Exit; {выход, если выбран пункт "Выход из программы"}

{или нажат Esc}

end;

until false;

end.