Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
19.doc
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
84.99 Кб
Скачать

19.1.2. Параметры-массивы.

Целые массивы компонентов могут появляться как фактические параметры в программах. Как и другие составные типы Паскаля, массивы обычно передаются по ссылке как параметры-переменные по соображениям эффективности. Если массив передается как параметр-значение, неявно присутствующая операция копирования должна будет скопировать каждый компонент. Однако, компоненты массивов могут эффективно связываться как с параметрами-значениями так и с параметрами-переменными. Определения раздела 9.1.4 не адекватны для случая алиасинга между индексным идентификатором и компонентом массива с таким индексом, переданным в параметре-значении.

Следующая программа обозначает некоторые сложности, которые могут возникнуть. Index передается параметру First, а Arr[Index] передается параметру Second. Таким образом, возникает алиасинг Second (через индекс Index) к First. First (или Index) инкрементируется до использования Second (или Arr[Index]). Однако, именно значение Arr[2], а не Arr[3] будет изменено, потому что связывание имени фактического параметра с именем формального параметра происходит при вызове процедуры, а не когда параметр-переменная используется.

PROGRAM Bind(INPUT, OUTPUT);

VAR

Arr: ARRAY [1..5] OF INTEGER;

Index: INTEGER;

PROCEDURE IncreaseParams(VAR First, Second: INTEGER);

BEGIN {IncreaseParams}

First := First + 1;

Second := Second + 1;

END; {IncreaseParams}

BEGIN {Bind}

FOR Index := 1 TO 5

DO

BEGIN

Arr[Index] := 1

END

Index := 2;

IncreaseParams(Index, Arr[Index]);

WRITELN(‘Index is’, Index:2);

FOR Index := 1 TO 5

DO

BEGIN

WRITELN(‘Arr[‘, Index:1, ‘] is ‘, Arr[Index] :2)

END

END. {Bind}

Выполнение:

OUTPUT: Index is 3

Arr[1] is 1

Arr[2] is 2

Arr[3] is 1

Arr[4] is 1

Arr[5] is 1

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

19.2. Реализация абстрактных типов данных с помощью массивов.

Абстракции данных, где конкретные объекты могут быть фиксированного размера, может быть эффективно реализована с использованием массивов.

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

19.2.1. Текстовые файлы ограниченного размера.

19.2.1. Стек ограниченного размера.

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

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

PROGRAM Reverse(INPUT, OUTPUT);

{Выводит первые Depth символов в INPUT в обратном порядке}

CONST

Depth = 20;

TYPE

EltType = CHAR;

Stack = RECORD

Val: ARRAY [1..Depth] OF EltType;

StackTop: 0..Depth

END;

VAR

S: Stack;

Elt: EltType;

PROCEDURE NewStack(VAR S: Stack);

{S := <>}

BEGIN {NewStack}

S.StackTop := 0;

END; {NewStack}

PROCEDURE Push(VAR S: Stack, E: EltType);

{S := S & <E>}

BEGIN {Push}

IF S.StackTop >= Depth

THEN

WRITELN(‘** OVERFLOW **’)

ELSE

BEGIN

S.StackTop := S.StackTop + 1;

S.Val[S.StackTop] := E

END

END; {Push}

PROCEDURE Pop(VAR S:Stack);

{Существуют Stack X, EltType E, такие что

S = X & <E> --> S := X}

BEGIN {Pop}

IF S.StackTop <= 0

THEN

WRITELN(‘** UNDERFLOW **’)

ELSE

S.StackTop := S.StackTop - 1

END; {Pop}

Function Top(VAR S: Stack);

{Существуют Stack X, EltType E, такие что

S = X & <E> --> Top := E}

BEGIN {Top}

IF S.StackTop <= 0

THEN

BEGIN

WRITELN(‘** READING EMPTY STACK **’);

Top := 0;

END

ELSE

Top := S.Val[S.StackTop]

END; {Top}

FUNCTION Empty(VAR S: Stack): BOOLEAN;

{Empty := (S = <>)}

BEGIN {Empty}

Empty := S.StackTop <= 0

END; {Empty}

FUNCTION Full(VAR S: Stack): BOOLEAN;

{Full := (Length(S) = Depth)}

BEGIN {Full}

Full := S.StackTop >= Depth

END; {Full}

BEGIN {Reverse}

NewStack(S);

WHILE NOT EOF AND NOT Full(S)

DO

BEGIN

Read(Elt);

Push(S, Elt);

END;

WHILE NOT Empty(S)

DO

BEGIN

WRITE(Top(S));

Pop(S)

END;

WRITELN

END. {Reverse}

Выполнение:

INPUT: abcdefghijklmnopqrstuvwxyz

OUTPUT: zyxwvutsrqponmlkjihgfedcba

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]