Взаимно рекурсивные подпрограммы 


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



ЗНАЕТЕ ЛИ ВЫ?

Взаимно рекурсивные подпрограммы



 

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

Program pr1(x:real);

forward;

procedure pr2(...);

{описание тела с вызовом pr1}

procedure pr1;

{ описание тела с вызовом pr2 };

 

 

21. КОМБИНИРОВАННЫЙ ТИП (ЗАПИСЬ)

 

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

Описание записи:

 
 

 


Идентификаторы - имена полей. Типы полей могут быть любыми.

Пример 1.

Const MaxLen = 25;

type t_range=1.. MaxLen;

t_date=record {Тип для работы с датами}

day: 1..31;

month: 1..12;

year: 0..9999

end; {end записано под соответствующим record}

t_student=record {Тип для хранения информации о студенте}

name: string[20];

birthday: t_date; {Поле-запись}

group: string[5];

marks: array[1..4] of 2..5

end;

t_group= array[t_range] of t_student;

var d1, d2: t_date; {Переменные для хранения дат}

group: t_group;{Переменная для хранения информации о студентах группы}

Над записями, как едиными целыми, не определены никакие операции. Совместимость по присваиванию требует тождественности типов. Для описанных выше переменных допустимы присваивания:

d1:=d2; group[1]: =group[25].

Обращение к полю записи представляет собой составное имя:

 

Составное имя можно использовать везде, где допустим тип поля. Например, d1.day:=5; read(group[1].name). Имена полей записей могут совпадать с именами других переменных, при этом путаницы не возникает, так как обращение к ним иное. Например, group - массив, group[i] - элемент массива, group[i]. group - поле i-й записи.

Пример 2. Процедура для определения даты следующего дня невисокосного года:

Procedure next_date(d1: t_date; var d2: t_date);

{d1 - данная дата, d2 - результат (дата следующего дня)}

var max: 28..31; {число дней в месяце}

begin d2:=d1;

case d2.month of {Определение числа дней в заданном месяце}

2: max:=28;

4, 6, 9, 11: max:=30

else max:=31

end;

if d2.day<max then d2.day:= d2.day+1

else begin d2.day:= 1;

if d2.month<12 then d2.month:= d2.month+1

else begin d2.month:= 1; d2.year:= d2.year+1

end

end

end;

Оператор присоединения

 

В Паскале есть возможность обращаться к полям записи без указания имени записи. Такую возможность дает оператор присоединения:

 
 

 


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

 
 

 

 


Пример 3. Описание процедуры ввода информации о студентах группы.

Procedure read_group(var gr: t_group; n: t_range); {n - число студентов}

begin write(‘Введите число студентов£’, MaxLen); read(n);

writeln(‘Введите. фам., даты рожд., группу и экз. оценки студентов.’);

for i:=1 to n do

with group[i], birthday do

begin read(name); {вместо gr[i].name}

readln(day, month, year); {вместо gr[i]. birthday. day,... }

read(group);

for j:=1 to 4 do

read(mark[j]); {вместо gr[i]. mark[j]}

readln

end

end;

 
 
With group[i], birthday do <оператор>


Оператор

 

with group[i] do with birthday do<оператор>
равносилен оператору

 

21.2. Записи с вариантами

 

Часто необходимы записи с близкими, но не одинаковыми структурами. Для таких случаев используется тип-запись с вариантами:

 
 

 

 


Вариантная часть:

 
 

 


Альтернатива:

 
 

 


В круглых скобках - список полей альтернативы (это ветвь вариантной части).

Для всех ветвей вариантной части выделяется одна и та же область памяти, где могут разместиться поля любой ветви. Идентификатор (дискриминант) определяет, какая из ветвей в данный момент активна. Но система не контролирует, к активным ли полям обращается программа. Ответственность за правильность использования полей ложится на программиста. Во избежание ошибок рекомендуется для обработки вариантной части использовать оператор-переключатель с селектором - значением дискриминантного поля.

Пример 4. Описание типа для хранения параметров любой из трех фигур: треугольника, прямоугольника или окружности:

type t_fig_type=(triangle, rectangle, circle);

t_figure = record

s: real; {площадь}

p: real; { периметр }

case fig_type: t_fig_type of

triangle: (a, b, c: real); {стороны треугольника}

rectangle: (d1, d2: real); { стороны прямоугольника}

circle: (r: real) {радиус окружности}

end;

Запись описанного типа содержит два фиксированных поля (s и p), полем-дискриминантом является вид фигуры (fig_type). Это поле может принимать одно из трех значений, поэтому вариантная часть содержит три ветви.

Пример 5. Описание процедуры инициализации переменной типа t_figure. Поля вариантной части вводятся с клавиатуры, а фиксированные поля вычисляются.

Procedure init_fig(var f:t_figure);

var n:byte;

begin write(‘Введите вид фигуры: 1-треуг., 2-прямоуг., 3-окружность’);

read(n);

with f do

begin

fig_type:= t_fig_type (n-1);

case fig_type of

triangle: begin read(a, b, c);

p:=(a+b+c)/2;

s:=sqrt(p*(p-a)*(p-b)*(p-c));

p:=2*p

end;

rectangle: begin read(d1, d2);

p:=(d1+d2)*2;

s:=d1*d2

end;

circle: begin read(r);

p:=2*Pi*r;

s:=Pi*r*r

end

end

end;

 

22. ПОБИТОВЫЕ ОПЕРАЦИИ

 

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

 

Название операции Запись на ТР Приоритет
Побитовое отрицание not m  
Побитовая конъюнкция n and m  
Побитовая дизъюнкция n or m  
Побитовое исключающее или n xor m  
Сдвиг влево n shl i  
Сдвиг вправо n shr i  

Побитовое отрицание инвертирует биты целого. nоt 1=0, not 128=127.

Для обнуления (сбрасывания) определенных битов целого числа выполняют побитовую конъюнкцию (побитовое умножение) данного числа с числом, называемым маской. Маска содержит нули только в тех битах, которые нужно сбросить, а в остальных битах - единицы. Например, при выполнении оператора x:=x and $FF00 сбрасывается младший байт двухбайтового целого ($FF00 - маска); при n:=n and ($FF-8) сбрасывается третий бит однобайтового целого. Биты нумеруются с нуля справа налево.

Побитовую дизъюнкцию можно использовать для установки единиц в определенных битах. При этом маска должна содержать единицы в устанавливаемых битах и нули - в остальных. Например, оператор

n:=n or (32+8)

установит 3-й и 5-й биты.

Побитовое исключающее или выполняет сложение соответствующих битов операндов по модулю 2 без переноса 1 в следующий разряд. Важное свойство операции xor: n xor m xor m=n.

При сдвиге влево биты левого операнда сдвигаются влево на число разрядов, равное значению правого операнда. Биты, выходящие за границы типа левого операнда пропадают, а освободившиеся разряды слева заполняются нулями. Сдвиг влево n shl i эквивалентен умножению n на 2i, если старшие разряды не вышли за левую границу n.

При сдвиге вправо биты левого операнда сдвигаются вправо на число разрядов, равное значению правого операнда. Биты, выходящие за правую границу, пропадают. Освобождающиеся слева разряды беззнакового целого заполняются нулями, а знакового - значением старшего (знакового) бита.

Сдвиг вправо n shr i эквивалентен целочисленному делению n на 2i в арифметике с положительными остатками. Например, n shl 5=n div 32.

Опишем процедуру вывода двоичного представления данного целого беззнакового числа:

 

Procedure WriteBinary(n:word);

var i:byte;

begin for i:=15 downto 0

write(n shl(15-i) shr 15)

end;

 

Поменять местами старший и младший байты целого неотрицательного числа можно с помощью оператора n:=(n shl 8) or (n shr 8).

 

23. ТИПИЗОВАННЫЕ КОНСТАНТЫ В ТP

 

TP позволяет инициализировать переменные при их описании. Описание с инициализацией переменных производится в разделе описаний констант:

 
 

 

 


Идентификатор - имя переменной.

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

Типизованная константа может быть: константой простого типа, константой-массивом, константой-строкой, константой-записью, константой-множеством, пустой ссылкой nil.

Типизованная константа простого или строкового типа представляет собой литерал или константное выражение. Константа-множество описывается обычным способом (см. главу 21). Например,

сonst n: integer=10;

c: char=’A’;

s: string[5]=’YES’;

f: real=1.3e-5;

m:set of 1..5=[1,3];

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

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

const a:array[1..3] of byte = (1,2,3);

Константа символьный массив может быть описана двумя способами: как константа-массив и как строковая константа. Например,

const digits1: array[0..9] of char = (‘0’,’1’,’2’,’3’,’4’,’5’,’6’,’7’,’8’,’9’);

digits2: array[0..9] of char = ‘0123456789’;

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

const b:array[1..2,1..3] of byte = ((1,2,3),(4,5,6));

(1,2,3) - первая строка, (4,5,6) - вторая строка матрицы.

Описание типизованной константы типа запись имеет вид

 
 

 

 


Обязательное условие: поля перечисляются в том же порядке, что и при описании типа. Например,

Type t_exam=record name: string[10];

marks: array[1..4] of 2..5

end;

Const exam: t_exam=(name: ’Иванов’; marks: (4, 3, 5, 4));

 

24. МНОЖЕСТВО

 

Описание типа множество:

 
 

 

 


Значениями типа множество являются все подмножества базового типа. Базовый тип играет роль универсального множества.

Число элементов базового типа множества ограничено. Ограничение определяется реализацией языка. В ТР число элементов базового типа не должно превышать 256. Базовый тип является перечисляемым типом или поддиапазоном перечисляемого типа. Кроме того, объем памяти, занимаемой значением базового типа, - один байт. Например, правильными описаниями являются: set of char, set of 10..100, set of ‘a’..’z’. Описания set of 200..300 и set of - 10..10 недопустимы, так как в первом случае базовый тип не является однобайтовым, во втором - перечисляемым.

Конструкция

 
 

 


определяет значение типа множество. При этом значения всех перечисленных выражений принадлежат одному типу. Порядок перечисления выражений и диапазонов произвольный. Более того, в списке могут быть выражения с одинаковыми значениями. Например, [5, 0, 3..10] - числовое множество, [‘0’..‘9’] - символьное множество, ['a','a','c'], ['c','a'] и ['a','c'] - равные символьные множества.

 



Поделиться:


Последнее изменение этой страницы: 2017-02-07; просмотров: 179; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.137.192.3 (0.051 с.)