Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
самост1_1new_druk!!!.doc
Скачиваний:
22
Добавлен:
13.11.2019
Размер:
1.61 Mб
Скачать

Тема: Підпрограми.

Рекурсивні підпрограми.

У ряді випадків потрібно, щоб підпрограма викликала сама себе. Такий спосіб виклику називається рекурсією. Рекурсія корисна в тих випадках, коли основну задачу можна розділити на підзадачі, кожна з яких реалізується за алгоритмом, що збігається з основним.

Приклад. Характерним випадком використання рекурсії є обчислення факторіалу. Згідно означення маємо: n1 = 1×2×…×(n-1) ×n=(n-1)! ×n, 0!=1, 1!=1.

function Factorial(n: integer): integer;

begin

if n<=О then Factorial:=1 else Fасt:=n*Fасtогіаl(n-l) ;

end;

Функція Factorial одержує в якості apryмeнтa число n і обчислює його факторіал. При цьому, якщо n менше або дорівнює нулю, то функція повертає значення 1, у протилежному випадку, зменшивши значення n на одиницю, функція знову викликає сама себе і так до тих пір, поки значення n не стане рівним нулю. Після цього відбувається послідовне обчислення значення факторіалу для значень 1,2,3, ..., n-1,n.

Функція Factorial і її параметр мають тип integer, що дозволяє обчислювати факторіал тільки для достатньо невеликих значень n. Для розширення діапазону допустимих значень можна використовувати тип Longint або дійсний тип.

Перетворення типів змінних і перетворення значень.

Турбо Паскаль має засіб, що дозволяє трактувати дані одного типу так, як би це були дані іншого типу. Цей засіб називається перетворення типів. Загальний вигляд перетворення типів:

<Тип>( <Змінна>)

Це означає, що для того, щоб використовувати змінну, що має свій певний тип, як змінну іншого типу, наприклад, присвоїти їй значення іншого типу, потрібно взяти цю змінну у дужки, а перед ними написати ідентифікатор цього іншого типу. Розмір змінної (кількість байтів, що займає змінна) повинен співпадати з розміром типу, представленого ідентифікатором <Тип>. Визначати допустимість приведення типу повинен програміст.

Приклад. Нехай змінна А має тип byte. Цій змінній не можна присвоїти значення символьного типу. Але коректним буде присвоєння Char(A):= 'D';

Близькою по синтаксису і за змістом є конструкція, що називається перетворення типу значення. Ця конструкція дозволяє перетворювати тип довільного виразу чи змінної. Загальний вигляд перетворення типу значення;

<Тип>(<Змінна або вираз>)

Значення змінної або виразу трактуються як дані типу <Тип>.

Наведемо характерний приклад. Нехай потрібно виділити старший молодший байти значення типу word. Наведемо фрагмент програми;

tуре TZap = record

10, hi: byte;

end;

var А, В: byte;

W: word;

begin

W:=23032;

А := TZap(W).lo; {виділення молодшого байта}

В := TZap(W).hi; {виділення старшого байта}

end.

Наведемо приклад застосування нетипованих параметрів-змінних:

function Equal(var source,dest; size: word): boolean;

type Bytes = array[0..Maxlnt] of byte;

var N: integer;

begin

N:=0;

while (N<size) and (Вytеs(dеst)[N] <> Bytes(source)[N] do Inc(N);

Equal := N - size;

end;

Ця функція приймає значення true (істинна), якщо дві змінних будь-якого розміру рівні між собою. Наприклад, за допомогою описів type Vector = array[1..10] of integer;

Point = record

x,у: integer;

end;

var Vecl, Vec2: Vector;

N: integer;

Р: Point;

і викликів функцій

Equal(Vecl, Vеc2, SizeOf(Vector));

Equal(Vecl, Vec2, SizeOf(integer)*N);

Equal(Vec[1], Vес1[6],SizeOf(integer)*5);

Equal(Vecl[1],P,4);

порівнюєrься Vеcl з Vес2, порівнюються перші N елементів Vесl з першими N елементами Vес2, порівнюються перші 5 елементів Vесl з останніми п'ятьма елементами Vес2 і порівнюються Vеc[l] з Р.x і Vес2[2] з Р.y.

Хоча нетиповані параметри дають велику гнучкість, їхнє використання, пов'язане з деяким ризиком. Компілятор не може перевірити допустимість операцій з нетипованими змінними.

Відкриті параметри-масиви.

Відкриті параметри дозволяють передавати одній і тій же процедурі чи функції рядки і масиви різних розмірів. Формальний параметр, описаний за допомогою синтаксису:

аrrау of Т є відкритим параметром-масивом. У такому описі Т ідентифікатор типу, а фактичний параметр повинен бути змінною типу Т чи масивом, типом елементів якого є Т. У процедурі чи функції формальний параметр є таким, ніби він був описаний у такий спосіб: array[0..N-1] of Т, де N - кількість елементів у фактичному параметрі. Діапазон індексів масиву, що є фактичним параметром, відображається в діапазон цілих чисел від 0 до N-1. Якщо фактичний параметр – це проста змінна типу Т, то він інтерпретується як масив з одним елементом типу Т. До відкритого формального параметра-масиву можна звертатися тільки поелементно. Присвоювання усьому відкритому масиву не допускаються. Відкритий параметр-масив може передаватися іншим процедурам чи функціям тільки як відкритий параметр-масив або нетипізований параметр-змінна.

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

До відкритих параметрів-масивів можна застосовувати стандартні функції Low, High і SizeOf. Функція Low повертає індекс першого елемента масиву, який вказаний у аргументі. Синтаксис функції: Low(Mas), де Mas ідентифікатор масиву. При застосуванні до відкритого параметра-масиву стандартна функція Low завжди повертає значення 0.

Стандартна функція High повертає індекс останнього елемента у масиві. Синтаксис функції: High(Mas), де Mas – ідентифікатор масиву. При застосуванні до відкритого параметра-масиву функція обчислює індекс останнього елемента масиву, який був переданий у підпрограму як фактичний параметр.

Стандартна функція SizeOf повертає розмір аргументу в байтах. Синтаксис функції: SіzеОf(М), де М – змінна чи константа будь-якого типу. При застосуванні до відкритого параметра-масиву функція повертає розмір фактичного параметра в байтах.

Приклад. Процедура Clear присвоює кожному елементу масиву дійсних значень нуль, а функція Sum обчислює суму всіх елементів масиву дійсних чисел. Оскільки в обох випадках параметр А є відкритим параметром-масивом, підпрограми можуть працювати з будь-яким масивом елементів типу Real:

procedure Clear(var А: аггау of Real);

var і: Word;

begin

for і:= 0 to High(A) do А[і] := 0;

end;

function Sum(const А: array of Real): Real;

var і: Word;

S: Real;

begin

S:=0;

for і := 0 to High(A) do S:= S+А[і];

Sum :=S;

end;

Питання для самоконтролю:

  1. Що називається рекурсією?

  2. Яким характерним прикладом є використання рекурсії?

  3. В яких випадках корисна рекурсія?

  4. Як здійснюється перетворення типів та перетворення значень в Паскалі?

  5. Як описуються параметри-масиви?