Студопедия

Главная страница Случайная лекция


Мы поможем в написании ваших работ!

Порталы:

БиологияВойнаГеографияИнформатикаИскусствоИсторияКультураЛингвистикаМатематикаМедицинаОхрана трудаПолитикаПравоПсихологияРелигияТехникаФизикаФилософияЭкономика



Мы поможем в написании ваших работ!




Design Part 1

PROGRAM Encryption(INPUT, OUTPUT);

{Переводит символы из INPUT в код согласно Chiper

и печатает новые символы в OUTPUT}

CONST

Len = 20;

TYPE

Str = ARRAY [1 .. Len] OF ‘A’ .. ‘Z’;

Chiper = ARRAY [‘A’ .. ‘Z’] OF CHAR;

VAR

Msg: Str;

Code: Chiper;

BEGIN {Encryption}

{Инициализировать Code}

WHILE NOT EOF

DO

BEGIN

{читать строку в Msg и распечатать ее}

{дополнить Msg пробелами}

{распечатать кодированное сообщение}

END

END. {Encryption}

 

Инициализация массива шифра это длинная последовательность присваиваний, поэтому она объединяется в процедуру.

 

Design Part 1.1.

{Инициализировать Code}

Initialize(Code);

Design Part 1.1.1.

PROCEDURE Initialize(VAR Code: Chiper);

{Присвоить Code шифр замены}

BEGIN {Initialize}

Code['A'] := 'Z';

Code['B'] := 'Y';

Code['C'] := 'X';

Code['D'] := '#';

Code['E'] := 'V';

Code['F'] := 'U';

Code['G'] := 'T';

Code['H'] := 'S';

Code['I'] := 'I';

Code['J'] := 'Q';

Code['K'] := 'P';

Code['L'] := '!';

Code['M'] := 'N';

Code['N'] := 'M';

Code['O'] := '2';

Code['P'] := 'K';

Code['Q'] := '$';

Code['R'] := 'D';

Code['S'] := 'H';

Code['T'] := '*';

Code['U'] := 'F';

Code['V'] := 'E';

Code['W'] := 'T';

Code['X'] := 'C';

Code['Y'] := 'B';

Code['Z'] := 'A';

END; {Initialize}

 

Символы считываются в последовательные элементы Msg до тех пор, пока не встретится маркер конца строки.

 

Design Part 1.2.

{читать строку в Msg и распечатать ее}

I := 0;

WHILE NOT EOLN AND (I < Len)

DO

BEGIN

I := I + 1;

READ(Msg[I]);

WRITE(Msg[I])

END;

READLN;

WRITELN;

Индекс I теперь находится в позиции последнего символа в сообщении и для очистки оставшейся части строки необходимо заполнить ее пробелами.

Design Part 1.2.

{дополнить Msg пробелами}

FOR I := I+1 TO Len

DO

BEGIN

Msg[I] := ‘ ‘;

END

Поскольку шифрование Msg занимает несколько строк кода, они оформляются процедурой.

Design Part 1.4.

{распечатать кодированное сообщение}

Encode(Msg)

Элементы Msg с ‘A’ по ‘Z’ используются как индексы в массиве Code для получения их кодированных значений. Другие символы распечатываются без перевода.

Design Part 1.4.

PROCEDURE Encode(VAR S: Str);

{Выводит символы из Code, соответствующие символам из S}

VAR

Index: 1 .. Len;

BEGIN {Encode}

FOR Index := 1 TO Len

DO

IF S[Index] IN [‘A’ .. ‘Z’]

THEN

WRITE(Code[S[Index]])

ELSE

WRITE(S[Index]);

WRITELN

END; {Encode}

Ниже приведен финальный текст программы и примеры ввода/вывода.

 

PROGRAM Encryption(INPUT, OUTPUT);

{Переводит символы из INPUT в код согласно Chiper

и печатает новые символы в OUTPUT}

CONST

Len = 20;

TYPE

Str = ARRAY [1 .. Len] OF ‘A’ .. ‘Z’;

Chiper = ARRAY [‘A’ .. ‘Z’] OF CHAR;

VAR

Msg: Str;

Code: Chiper;

{Включить PROCEDURE Encode(VAR S: Str);}

{Включить PROCEDURE Initialize(VAR Code: Chiper);}

BEGIN {Encryption}

{Инициализировать Code}

Initialize(Code);

WHILE NOT EOF

DO

BEGIN

{читать строку в Msg и распечатать ее}

I := 0;

WHILE NOT EOLN AND (I < Len)

DO

BEGIN

I := I + 1;

READ(Msg[I]);

WRITE(Msg[I])

END;

READLN;

WRITELN;

{дополнить Msg пробелами}

FOR I := I+1 TO Len

DO

BEGIN

Msg[I] := ' ';

END

{распечатать кодированное сообщение}

Encode(Msg)

END

END. {Encryption}

 

Выполнение:

INPUT: NOW IS THE TIME

END

OUTPUT: NOW IS THE TIME

M2T IH *SV *INV

END

VM#

 

19.1.1. Синтаксис и семантика для массивов.

 

Следующие синтаксические правила описывают тип данных массив.

 

<составной тип> ::= <неупакованный структурированный тип>

<неупакованный структурированный тип> ::= SET OF <базовый тип>

| FILE OF <тип компонентов>

| RECORD <список полей> END

| ARRAY [<список индексного типа>] OF <тип компонентов>

<список индексного типа> ::= <список индексного типа>, порядковый тип

| <порядковый тип>

 

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

 

<переменная> ::= <идентификатор переменной> | <переменная буфера>

| <переменная-компонент>

<переменная-компонент> ::= <описатель поля> | <индексированная переменная>

<индексированная переменная> ::= <переменная массива> [<список выражений>]

<переменная массива> ::= <переменная>

<список выражений> ::= <список выражений>, <выражение> | <выражение>

 

Формально, значения соответствующие переменным массивов в состоянии выполнения являются отношениями. В парах отношения массив-значения первые элементы принадлежат конечному множеству значений индексного типа, а вторые элементы множеству значений типа компонентов. Таким образом, количество возможных значений переменой массива велико. Каждый индекс может находится в паре с любым из возможных значений компонента, так что для N индексов и M возможных значений компонентов, массив может иметь MN значений, каждое из которых представляет из себя соответствие значений индексам. Например, переменная:

VAR

Carray: ARRAY [1..3] OF CHAR;

имеет 1283 ~ 2 100 000 возможных значений для Паскаль-машины со 128 символьными значениями, одним из которых будет {<1, X>, <2, B>, <3, 3>}. Это значение может быть результатом присваивания:

CArray[1] := ‘X’;

CArray[2] := ‘B’;

CArray[3] := ‘3’;

Раз каждый индекс в массиве имеет присвоенный ему компонент, значение массива должно быть функцией. Однако, до тех пор пока индекс остается несвязанным, эта часть массива подобна неинициализированной переменной. Например, если к CArray были применены только первое и третье присваивания, его значение будет:

{<1, X>, <3, 3>}È{ <2, c>: c - символ},

которое мы обычно сокращаем до

{<1, X>, <3, 3> <2, ?> }.

Эти значения могут появляться в состоянии выполнения с идентификатором массива.

S = {CArray·{<1, X>, <3, 3> <2, ?> }, ...}

Значение <индексированной переменной> может быть получено может быть получено из значения соответствующего массива. Например для приведенного выше состояния S:

CArray[1](S) = X

В общем, для идентификатора массива A и индекса I, где I принадлежит типу J:

A[I] = {<s, v>: s(I) является значением типа J, v = (s(A))(s(I))}

Определение присваивания (раздел 6.2.1) применимо к массивам без изменений, но не покрывает случай, где элемент массива находится в левой части присваивания. В этом случае присваивание завершается с ошибкой, если значение индекс не является допустимым значением соответствующего типа. Формально, для индекса I типа J:

A[I] := E = {<s, t>: I(s) является значением типа J, t =s,

за исключением того, что A[I](t)=E(s)}

Во всех других случаях значение выражения становится присоединенным к идентификатору в левой части в состоянии выполнения после выполнения оператора.

Когда оператор присваивания присваивает один идентификатор массива другому идентификатору, его значением становится отношение, представляющее значение массива в целом.

 

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

 

 


<== предыдущая страница | следующая страница ==>
Проектирование программ в O Pascal | Балаково 2009

Дата добавления: 2014-11-01; просмотров: 242; Нарушение авторских прав




Мы поможем в написании ваших работ!
lektsiopedia.org - Лекциопедия - 2013 год. | Страница сгенерирована за: 0.008 сек.