Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Практикум по основам программирования. Язык Паскаль

.pdf
Скачиваний:
9
Добавлен:
15.11.2022
Размер:
6.27 Mб
Скачать

названии и количестве полей каждой записи, а также в форме задания внешнего имени файла в операторе REWRITE.

3. Программа, приведенная ниже, обеспечивает добав­ ление во внешний упорядоченный по неубыванию цен товаров файл одной записи. Она может быть принята за основу при разработке программы, которая добавля­ ет во внешний упорядоченный файл М записей. Для этого достаточно повторить в цикле М раз те дейст­ вия, которые производились при добавлении одной за­ писи. Следует также помнить, что в операторах REWRITE и RESET надо использовать внешние имена файлов, принятые в данной вычислительной системе.

PROGRAM 23(1NPUT, OUTPUT); TYPE ZAP=RECORD

HA3B: PACKED ARRAYCl..103 OF CHAR; ЦЕНА:INTEGER

END; TOB=FILE OF ZAP;

VAR^NEW,OLD:TOB; B:ZAP; I:INTEGER;

BEG I N

(* ВВОД С ТЕРМИНАЛА ПОЛЕЙ НОВОЙ ЗАПИСИ *)

R EADLN; WRITE ('*=>') ;

 

pOR •I:=1

TO

10 DO READ(В.HA3BC13);

R EADLN(В.ЦЕНА);

 

(* ОТКРЫТИЕ

ФАЙЛОВ *>

 

RESET(OLD, OLD.DAT');

 

REWRITE(NEW, NEW.DAT *);

 

(• ВСТАВКА НОВОЙ ЗАПИСИ *)

AND (OLDT.ЦЕНА<*В.ЦЕНА) DO

WHILE (OLDT.HA3B< >***********')

BEGIN

NEWT:“OLDT; PUT(NEW);

GET(OLD) END»

MEWT:»B;

PUT(NEW);

 

REPEAT

 

NEWT:“B;

 

В:“OLDT;

 

PUT(NEW);

GET(OLD)

 

UNTIL В.HA3B“ ***********';

CLOSE(NEW);

<« ПЕРЕПИСЬ ДАННЫХ ИЗ НОВОГО ФАЙЛА В СТАРЫЙ И ИХ ПЕЧАТЬ *> RESET(NEW,'NEW.DAT');

REWRITE(OLD,'OLD.DAT'); REPEAT

В:-NEWT; OLDT:“B;

PUT(OLD); GET(NEW);

WRITELN(В.HA3B,В.ЦЕНА) (* ВЫВОД НА ТЕРМИНАЛ •> UNTIL В.НАЗВ='**********';

CLOSE(OLD) ENP-

В а р и а н т ы з а д а н и я

1. Товары упорядочены по неубыванию цены, N=10, М=3.

ш

2.Товары упорядочены по неубыванию года выпуска, N=9; М=4.

3.Товары упорядочены по неубыванию количества, N=11, М=4.

4.Товары упорядочены по невозрастанию цены, N=9, М=6.

5.Товары упорядочены по невозрастанию года выпу­ ска, N=7, М=3.

6.Товары упорядочены по невозрастанию количества, N=12, М=5.

7.Товары упорядочены по неубыванию цены, N=13, М=4.

8.Товары упорядочены по неубыванию года выпуска, N=10, М=3.

9.Товары упорядочены по неубыванию количества, N=13, М=6.

10.Товары упорядочены по невозрастанию цены, N=12, М=4.

11.Товары упорядочены по невозрастанию года выпу­ ска, N=11, М=3.

12.Товары упорядочены по невозрастанию количества, N=10, М=3.

13.Товары упорядочены по неубыванию цены, N=7, М=5.

14.Товары упорядочены по неубыванию года выпуска, N=8, М=5.

15.Товары упорядочены по неубыванию количества, N=7, М=6.

16.Товары упорядочены по невозрастанию цены, N=8, М=5.

17.Товары упорядочены по невозрастанию года выпу­ ска, N=9, М=4.

18.Товары упорядочены по невозрастанию количества, N=8, М=6.

19.Товары упорядочены по неубыванию цены, N=8, М=3.

20.Товары упорядочены по неубыванию года выпуска, N=11, М=5.

Г Л А В А 8

ССЫЛОЧНЫЕ ТИПЫ ДАННЫХ

Переменные рассмотренных ранее типов данных называ­ ют статическими, так как по имени переменной осуще­ ствляется обращение к заранее (во время трансляции) зарезервированной области памяти. Иногда возникает необходимость в динамическом порождении объектов и размещении их в памяти ЭВМ во время выполнения программы. Такая ситуация может встретиться, когда ко­ личество объектов в программе заранее не известно и отвести достаточное место в памяти невозможно.

8.1. ДИНАМИЧЕСКИЕ ПЕРЕМЕННЫЕ

Динамическая переменная не указывается явно в описаниях переменных и у нее нет имени. Для досту­ па к динамическим переменным предназначены пере­ менные специального типа данных, называемого ссы­ лочным.' Ссылочный тип данных задается как!<тип>. Переменная ссылочного типа может указывать на ди­

намические объекты только заданного типа. Например, описание

TYPE TMINTEGER;

VAR А:Т; В:f REAL;

означает, что ссылочная переменная А указывает на динамические объекты целого типа, а ссылочная пере­ менная В - н а динамические объекты вещественного типа.

Ссылочной переменной может быть присвоено "пустое" значение адреса, обозначаемое служебным сло­ вом NIL. Оператор присваивания A:=NIL означает, что ссылочная переменная А не указывает ни на один ди­ намический объект. Память под переменные А и В отводится на этапе трансляции.

Для порождения динамических объектов предназ­ начена стандартная процедура NEW(A), где А - пара­ метр ссылочного типа. После работы процедуры NEW(A) переменная А получает значение ссылки на порожденный объект. Чтобы получить доступ к дина­ мически выделенной памяти, необходимо написать A f, что означает "идти по адресу, хранящемуся в А". На-

пример, во фрагменте программы

VAR X.Y: / INTEGER;

NEW(X); Х/:=13; Y:=X; WRITELN(Y/); WRTTELN(X/+20);

сначала динамически порождается объект целого типа. 'Это означает, что выделяется место в памяти, но ни­ чего туда не заносится. При этом переменной ссылоч­ ного типа X присваивается значение адреса динамиче­ ского объекта. Оператор присваивания Xf: =13 заносит целое число 13 в динамическую переменную. Ссылоч­ ная переменная Y может содержать адрес любого объ­ екта целого типа, поэтому правомерен оператор при­ сваивания Y:=X. Он заносит в переменную Y значение того же адреса, что хранится в переменной X. Первый оператор печати выведет целое число 13, а вто­ рой - число 33. Но при этом целочисленное значение, хранящееся в динамической переменной, не изменится (рис. 8.1).

Рис. 8.1

Для уничтожения динамических объектов служит стандартная процедура DISPOSE(X), где X-переменная ссылочного типа. После окончания работы процедуры ссылочной переменной X присваивается значение NIL, а память, занимаемая динамической переменной, осво­ бождается.

8.2. ДИНАМИЧЕСКИЕ СПИСКОВЫЕ СТРУКТУРЫ

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

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

му. Тогда, чтобы осуществить операцию исключения, достаточно выполнить следующий оператор присваива­ ния:

ПРЕДt.С: =ПРЕД t.C t.C

Правая часть оператора присваивания читается так: идти по ссылке, хранящейся в ПРЕД, взять ссыл­ ку из поля С, идти по ней, взять ссылку из поля С удаляемого элемента. Полученное ссылочное значение записывается в поле С элемента, предшествующего удаляемому.

Чтобы вставить элемент в произвольное место связанного списка, кроме начала, также необходимо из­ менить только значения указателей. Сами элементы

списка

при этом не перемещаются. Например,

на

рис. 8.4

показано включение в связанный список

эле­

мента X.

 

ПОС

X

Рис. 8.4

Пусть ссылочная переменная ПОС указывает на элемент, после которого необходимо вставить в список элемент X. На элемент X указывает ссылочная пере­ менная НОВ. Операция вставки реализуется двумя операторами присваивания:

НОВ t.C:=ПОС t.C; ПОС t.C: =НОВ

Первый оператор заносит в поле ссылки вставляе­ мого элемента ссылочное значение, указывающее на элемент В и содержащееся ранее в F. Второй оператор

записывает в поле ссылки элемента F ссылку на встав­ ляемый элемент.

гас

N I L

NIL

 

D

В

Рис. 8.5

Для

добавления

в конец списка элемента X

Грис. 8.5)

достаточно

найти

последний элемент списка

(у него поле ссылки

имеет

значение NIL) и переслать

в его поле ссылки указатель на добавляемый элемент. При этом поле ссылки добавляемого элемента должно содержать NIL.

Эти действия реализуются операторами

НОШ.С:= NIL; ПОС1.С: = НОВ;

Приведенный пример является частным случаем добавления элемента в список.

НАЧ

Рис. 8.6

Обычно при построении связанных списков вводят ссылочную переменную, указывающую на начало спи­ ска, на его первый элемент. Поэтому при удалении первого элемента (рис. 8.6, а) или при вставке нового элемента в начало списка (рис. 8.6, б) необходимо пе­ реопределять не указатель предыдущего элемента, как в рассмотренных выше примерах, а значение началь­ ного указателя.

Операция удаления реализуется одним оператором HA4:=HA4t.C, а операция вставки - двумя оператора­ ми: НОВ f.С: =НАЧ; НАЧ:=НОВ.

8.3.ВОПРОСЫ И УПРАЖНЕНИЯ

1.Каково назначение переменных ссылочного типа, процедур NEW и DISPOSE?

2.Как распределяется память под переменные ссылоч­ ного типа?

3*. Указать значения X t и Yt после выполнения сле­ дующих операторов:

NEW(X); x t : = 17; NEW(Y); Yf:= -5 ; X t:=X t+Y f; Yt:=Yt+12;

если известно, что VAR X,Y:tINTEGER.

4*. Что будет напечатано после выполнения следую­ щих операторов:

NEW(X); X t= ’A’; WRTTE(Xf); Y:=X; WRITELN(Yf);

если известно, что VAR X,Y:tCHAR; ?

5*. Разделы типов и переменных в программе имеют вид

TYPE A=tCHAR; B=RECORD S1:CHAR;

S2:A

END;

VAR X:tB; Y:A;.

Что будет выведено на печать после выполнения следующих операторов:

NEW(Y); Y t:=’A’; NEW(X); Xt.Sl>=SUCC(Yt); Xf.S2:=Y; WRITELNCY1 ,Xf Sl,Xt.S2 ) ?

6*. Известно, что:

TYPE CCblJlKA=TREAL;

BEKTOP=ARRAYCl..50] OF ССЫЛКА;

VAR X:ВЕКТОР;

Считая, что все элементы массива X отличны от NIL, написать:

а) фрагмент программы для нахождения наиболь­ шего из чисел, на которые ссылаются элементы мас­ сива X;

б) фрагмент программы, который переменной

NEG присваивает

значение первого элемента массива

X, ссылающегося на отрицательное число, или NIL, ес­

ли такого нет.

переменных: VAR X,Y: 1 INTEGER;

7*. Дано описание

R:f CHAR;

 

Какие операторы являются правильными, какие-нет и почему?

a) X:=Y; б) Y:=R; в) X:=NIL; г) R:=NIL;

д) IF Y=X THEN Х1:=21; е) IF Y < X THEN Yf:=X ;

8*. В программе определены следующие типы и переменные:

TYPE ССЫЛКА=?ЭЛЕМЕНТ; 5J1EMEHT=REC0RD СЛЕД: ССЫЛКА;

Д:INTEGER

END;

VAR НАЧ,С ,В:ССЫЛКА; I:INTEGER;

Даны два фрагмента программы: Первый фрагмент:

...NEW(С); НАЧ:=С; FOR 1:=1 ТО 10* DO

BEGIN NEW(В); СТ.СЛЕД:=В;' СТ. Д: =1; С: -В

END;...

Второй фрагмент:

...NEW(С); НАЧ:=С;

WITH СТ DO

FOR I:=l ТО 10 DO

BEGIN NEW(В); СЛЕД:-В; Д:=1; С:=В

END; .

Определить, будут ли одинаковыми результаты ра­ боты приведенных фрагментов программы, и если нет, то почему.

8.4. ПРАКТИЧЕСКИЕ ЗАДАНИЯ

З А Д А Н И Е 1. ФОРМИРОВАНИЕ СПИСКА С ОДНОВРЕМЕННЫМ УПОРЯДОЧЕНИЕМ ЕГО ЭЛЕМЕНТОВ

Ц е л ь з а д а н и я 1. Ознакомление с динамической структурой дан­

ных - однонаправленным списком.

2. Получение навыков работы с переменными ссылоч­ ного типа.

П о с т а н о в к а з а д а ч и Для конкретного варианта составить входную ин­

формацию. Разработать программу, которая обеспечива­ ет последовательное занесение информации в однонап­ равленный список с одновременным упорядочением по указанному в варианте признаку. По окончании формирования списка распечатать его.

С о д е р ж а н и е о т ч е т а

1.Постановка задачи.

2.Исходные данные.

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

4.Анализ допущенных ошибок.

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

программу, которая вводит с терминала названия учеб­ ников (последнее название является фиктивным, оно характеризует конец списка и состоит из десяти букв Я), динамически отводит место в памяти под каждое название и строит из них связанный список, упорядо­ ченный по алфавиту. По окончании формирования ка­ талог книг выводится на терминал. Использование списковых структур при решении подобных задач име­

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

PROGRAM СЛИСОК(INPUT,OUTPUT>|

TYPE HA38-PACKED ARRAY!1..10] OF CHAR* ССЫЛКА«?ЭЛЕМЕНТ|

ЭЛЕМЕНТ-RECORD CCxССЫЛКА; ДАНxHA38

END;

VAR КНИГАХHA381 НАЧ,ТЕК,ОБ,ОБПРхССЫЛКА; lx INTEGER; BEGIN

(* ФОРМИРОВАНИЕ 1-ГО ЭЛЕМЕНТА СПИСКА *>

NEW(НАЧ); READLN; WRITELN('ВВОДИ ПЕРВОЕ НАЗВАНИЕ*); FOR Iх—1 ТО 10 DO READ(КНИГА!ID); READLN; НАНТ.CCx-NIL; НАНТ.ДАНх-КНИГА;

(* ФОРМИРОВАНИЕ СПИСКА *) WHILE КНИГА<>'ЯЯЯЯЯЯЯЯЯЯ * DO

BE6IN

ТЕКх-НАЧ; NEW(ОБ);

WRITELN( В80ДИ ОЧЕРЕДНОЕ НАЗВАНИЕ*);

FOR Iх—1 ТО 10 DO READ(КНИГА!IЭ); READLN; (* ПОИСК ПОДХОДЯЩЕГО МЕСТА *)

WHILE (TEKONIL) AND (ТЕКТ.ДАН<КНИГА) DO

BEGIN

(* ССЫЛКА НА ПРЕД.ЭЛЕМЕНТ *)

ОБПРх-ТЕК;

ТЕКх-ТЕКТ.СС

(* ПЕРЕХОД К СЛЕД.ЭЛЕМЕНТУ *!

END;

 

(* ВСТАВКА НОВОГО ЭЛЕМЕНТА *)

 

ОБ?.ССх—ТЕК;

 

ОБ?.ДАНI-КНИГА;

 

IF ТЕК-НАЧ THEN НАЧх-06 ELSE ОБПР?.ССх»ОБ END; (* КОНЕЦ ФОРМИРОВАНИЯ СПИСКА *)

(* ВЫВОД НА ТЕРМИНАЛ УПОРЯДОЧЕННОГО КАТАЛОГА КНИГ *) WRITELN(КАТАЛОГ УЧЕБНИКОВ!*);

ТЕКх-НАЧ; WHILE TEK?.CC<>NIL DO

BEGIN WRITELN(ТЕК?.ДАН); ТЕКх-ТЕК?.СС

END

END.

В начале программы формируется первый эле­ мент списка и задается значение начального указателя НАЧ. Затем, пока не будет введено название учебника, состоящего из десяти букв Я, под каждое вводимое на­ звание динамически отводится место в памяти опера­ тором NEW(OB), после чего просматривается список с самого начала до тех пор, пока не будет найдена соот­ ветствующая позиция для нового элемента или не бу­ дет достигнут конец списка. В найденное место встав-

110