Практикум по основам программирования. Язык Паскаль
.pdfназвании и количестве полей каждой записи, а также в форме задания внешнего имени файла в операторе 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