Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по программированию..pdf
Скачиваний:
10
Добавлен:
15.11.2022
Размер:
12.2 Mб
Скачать

Program Sr;

10000;

 

 

 

 

Const

NMax ■

 

 

 

 

Type Diapazon * l..NMax;

 

 

 

Maslnt

® Array[Diapazon] Of

Integer;

Var

MasReal ■ Array[Diapazon] Of Real;

 

Plint

"Maslnt;

 

 

 

 

PReal

"MasReal;

 

 

 

 

I, Midint

longlnt;

 

 

Begin

MidReal

 

Real;

 

 

 

MidReal

:* 0;

 

 

 

 

 

 

 

 

Midint

 

:в 0;

 

 

 

 

 

Randomize;

 

 

 

 

 

NEW (PReal);

{Выделение памяти под вещественный массив}

 

{Вычисление и суммирование вещественного массива}

 

For I

 

1 То NMax Do

 

 

 

Begin PReal"[I]

:= Random;

 

 

 

MidReal := MidReal + PReal"[I]

 

End;

 

 

 

{Удаление вещественного массива}

 

DISPOSE(PReal);

 

NEW(Pint);

 

{Выделение памяти под целый массив}

 

{Вычисление и суммирование целого массива}

 

For I

;* 1 То NMax Do

 

 

 

Begin

 

 

:■ Random(200)

- 100;

 

Pint"[I]

 

Midint := Midint + Pint"[I]

 

 

End;

 

средних значении}

 

 

 

{Вывод

 

 

Midint Div NMax);

 

WriteLn(*среднее целое равно:

 

WriteLn(’среднее вещественное равно:

End.

 

 

(MidReal / NMax)

10

6)

 

 

 

 

 

 

 

15.2.Связанные списки

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

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

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

Во-первых, динамическая память позволяет хранить больший объем информации, чем статическая. А во-вторых, в динамической памяти эти числа можно организовать в связанный список, который не тре­ бует предварительного указания количества чисел, подобно массиву. Что же такое “связанный список” ? Схематически он выглядит так:

х х Р2

я2 Рз

Яз Р4

х$ Nil

Каждый элемент списка состоит из двух частей: информационной части (#i, #2 и т.д.) и указателя на следующий элемент списка (р2, Рз и т.д.). Последний элемент имеет пустой указатель Nil. Связанный список такого типа называется однонаправленной цепочкой.

Для сформулированной выше задачи информационная часть — это вещественные числа. Х\ — результат первого измерения, х2 — резуль­ тат второго измерения и т.д., х± — результат последнего измерения. Связанный список обладает тем замечательным свойством, что его можно дополнять по мере поступления новой информацииДобавле­ ние происходит путем присоединения нового элемента к концу списка. Значение N il в последнем элементе заменяется ссылкой на новый эле­ мент цепочки:

X I Р2

Х 2 Рг

*3 i Pi —*\хА рь — ► 25

Связанный список не занимает лишней памяти. Память расходуется

втом объеме, который требуется для поступившей информации.

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

Туре Ре и "Elem;

Elem - Record

Т

Real;

Р

Ре

End;

 

Здесь Ре — это ссылочный тип на переменную типа ElemПод .{этим именем обозначен комбинированный тип, состоящий из д£Ух полей: Т — вещественная величина, хранящая температуру, Р — указатель на динамическую величину типа Elem.

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

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

Рассмотрим программу формирования связанного списка в ходе ввода данных.

Туре Ре * "TypElem; TypElem « Record

 

Т

Real;

 

Р

Ре

 

End;

Var Elem, Beg

Pe;

X

Real;

 

N

Integer;

 

Ch

Char;

 

Begin {Определение адреса начала списка и его сохранение}

NEW(Elem); Beg := Elem;

ElenT.P := Elem;

{Диалоговый ввод значений с занесением их в список

и организацией связи мехду элементами}

While ElenT.P <> Nil Do

Begin

Write О Вводите число: ');

Readln(X);

ElenT.T := X;

Write('Повторить адсд? (Y/N)');

ReadLn(Ch);

If (Ch = 'n') Or (Ch = 'N')

Then ElenT.P := Nil

Else Begin

NEW(Elem".P);

Elem:=ElenT .P

End

End;

Writeln('BBon данных закончен');

{Вывод полученной числовой последовательности}

WriteLn('Контрольная распечатка');

N :=

1;

 

Elem

:= Beg;

 

Repeat

ElenT.T 8 3);

Writeln(N,

N

:= N + 1;

 

Elem := ElenT.P

 

Until

Elem = Nil

 

End.

Procedure INSTEK(Var Beg Pe; Sim Char);

Var X Pe;

Begin New(X);

X".C :« Sim;

X".P Beg;

Beg :» X

End;

В процедуре OUTSTEK параметр Beg играет ту же роль, что и в пре­ дыдущей процедуре. После удаления последнего символа его значение станет равным Nil. Ясно, что если стек пустой, то удалять из него нечего. Логический параметр Flag позволяет распознать этот случай. Если на выходе из процедуры Flag = True, то значит удаление произо­ шло; если Flag = False, значит стек был пуст и ничего не изменилось.

Процедура “не оставляет после себя мусора” , освобождая память из под удаленных элементов.

Procedure OUTSTEK(Var Beg Pe; Var Flag Boolean);

Var X: Pe;

Begin

If Beg » Nil

Then Flag :* False

Else

Begin

Flag :* True;

X := Beg;

Beg := Beg".P;

DISPOSE(X)

End

End;

Задания

1. В программе имеются описания:

Var Р, Q "Integer; R "Char;

Какие из следующих операторов неправильные и почему?

а) Р

 

Q;

б) Q

:= R;

в) Р := Nil;

г) R

:= Nil;

д) q

:* Р";

е) Р"

:= Nil;

ж) R~

:в Р~;

о) Q~

Ord(R");

и) If

R

<>

Nil Then R" := Nil";

к) If q > Nil Then q"

л) If

P

- q Then Write(q);

M ) If Q<> RThen Read(R").

2. В программе имеются описания:

Туре А = "Char;

В = Record

FI Char;

F2 А

End;

Var Р "В; Q А;

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

NEW(Q);

Q" := *7»;

NEW(Р);

P~.F1 :« Succ(Q");

P".F2 := Q;

3. Найти ошибки в следующей программе:

Program Example;

Var A,

В

"Integer;

Begin

If A = Nil

Then Read(A);

 

A"

:= 5;

 

 

В

Nil;

 

 

B"

:= 2;

 

 

NEW(B);

 

 

Read(B");

B");

 

WriteLn(B,

 

NEW(A);

 

 

В

:= A;

 

 

DISPOSE(A);

End.

B"

:= 4

 

 

 

 

4. Составить программу занесения в динамическую пам£ть вещест­ венного массива из 10000 чисел, хранящегося в файле на магнитном диске, а также поиска в нем значения и номера первого ма#симйлъного элемента.

5. Решить предыдущую задачу при условии, что размер делового массива заранее не определен (определяется размером фа$ла: предпо­ лагается, что размер файла не превышает размера динаМ^че^кой па­ мяти). Данные в динамической памяти организовать в виде свяЬанного списка.

6. Связанный список представляет собой символьную цепочку из строчных латинских букв. Описать процедуру или функцию, которая

а) определяет, является ли список пустым; б) заменяет в списке все вхождения одного символа на вхождения

другого; в) меняет местами первый и последний элементы непустого списка;

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

раз.

7.Составить тестовую программу, проверяющую правильность ра­ боты процедур INSTEK и 0UTSTEK из задачи о стеке.

8.Очередью называется динамическая структура (связанная це­

почка), в которой действует принцип: “Первым пришел — первым вышел” . Напишите процедуры включения элемента в очередь и ис­ ключения элемента из очереди. Составьте тестовую программу, про­ веряющую работу процедур.