понеділок, 15 вересня 2014 р.

Поняття підпрограми-функції

 Поняття підпрограми-функції


Другим видом підпрограм є функції, які характеризуються тим, що в результаті їх виконання одержується лише один результат. Тоді як процедура може повертати один, кілька або жодного результату.
Загальний опис функції:              алг <тип_результату> Ім'я функції (<формальні параметри>)
                           арг <список аргументів>
                           рез <результат>
              поч
                     <опис дій>
                     знач: = <ім'я змінної, що містить результат> або <вираз для обчислення>
              кін
Опис на Pascal:
             function <Назва функції> (<формальні параметри>): <тип результату>
                     <описова частина>;
             
begin                 <опис операторів>;
                 <назва функції>:= <ім'я змінної, що містить результат> або <вираз для обчислення>
             end;

Як і в процедурі в заголовку функції описуються формальні параметри (проте їх може і не бути), а з основної частини програми здійснюється виклик для фактичних параметрів.
Функція, як і процедура, може використовувати в обчисленнях глобальні змінні (описані на початку основної програми), так і свої локальні змінні (описані безпосередньо в функції і доступні лише їй).
Отже, процедура і функція мають ряд подібностей. Але є й відмінності.
       По-перше, заголовок функції обов'язково містить тип результату. Процедура ж може повертати кілька різнотипних результатів, тому така характеристика для неї була б проблематичною.
       Друга відмінність полягає в способі повернення результатів роботи підпрограми в основну програму. Пересилання результатів у функції здійснюється по її назві (<назва функції>: = <ім'я змінної, що містить результат> або <вираз для обчислення>). Тоді як у процедурі використовується службове слова Var перед параметрами-змінними.
      По-третє, функція може входити до складу виразів. Подібне ж використання процедури буде помилковим. Наприклад, вираз НСД(a1, b1, rez1) + НСД(a2, b2, rez2) не має змісту, де НСД - розглянута нами раніше (Урок_15) процедура. Використання ж функції у складі виразу розглянемо на цьому уроці трохи пізніше.


 
Задача
Змій Горинич вирішив створити свій стільниковий оператор Snake. Три голови ніяк не могли домовитись, скільки цифр повинно бути в номері телефону, проте відразу погодились, що всі цифри мають бути різні. Підкажіть Гориничу, скількох абонентів він зможе підключити, якщо номер буде к-значний, а цифри обиратимуться з n варіантів.

Розв'язання
Для обчислень на потрібно вміти обчислювати факторіал, причому оформити обчислення як допоміжний алгоритм. Нагадаємо, щоn!=1*2*3*...*n, причому 0!=1 і 1!=1.
Приклад. 4!=1*2*3*4. rez : =1, rez : = rez*2= 1*2= 2, rez : = rez*3= 2*3= 6, rez : = rez*4= 6*4= 24.
Зрозуміло, що для обчислення n!, потрібно організувати цикл n раз, в якому попереднє значення множити на номер кроку обчислень (на 2-ому кроці множимо на 2, ...).
Для усвідомлення відмінностей між процедурою та функцією розглянемо алгоритми процедури та функції.
      Алгоритм процедури
алг Факторіал (ціл p, ціл rez)
     арг  p
     рез  rez
поч   ціл i
   rez:= 1
   для i від 1 до p
   пц
       rez:= rez*i
   кц
кін
     Алгоритм функції
алг ціл Факторіал (ціл p)
       арг p
поч
     ціл i
     rez : = 1
     для  i  від 1 до p
     пц
         rez : =  rez * i
     кц
     знач : = rez
кін


Зверніть увагу:
 Алгоритм процедури
            
 Алгоритм функції
 У заголовку описуються як аргументи, так і результати
       
  У заголовку описуються лише аргументи
  Біля слова "алг" не вказується тип результату
 
  Біля слова "алг" вказується тип результату
 Передбачається, що змінні, описані як результати, будуть параметрами-змінними (при перекладі на Pascal біля писатиметься Var)
 
 Повернення результату забезпечується командою знач := результат (знач на Pascal перекладеться як назва функції)
Перекладемо на Pascal обидва алгоритми.
procedure Faktorial (p : integer, Var rez : longint);
                                 {rez - довге ціле}
Var
     i : integer;
begin
     rez : = 1;
     for i : =1 to p do
     begin
         rez : = rez * i;
     end;
end;
function Faktorial (p : integer) : longint;
  Var
       i : integer;
       rez : longint;
begin
      rez : = 1;
      for i : =1 to p do
      begin
           rez : = rez * i;
      end;
      Faktorial : = rez;
end;
Зверніть увагу:
 Фрагмент програми процедури

 Фрагмент програми функції
У заголовку описуються аргументи і результати (перед останніми пишеться Var), а також їх типи
       
 У заголовку описуються лише аргументи та їх типи
 У заголовку немає вказівок на тип результату вказується тип результату

 Після назви функції та переліку формальних параметрів після ":" вказується тип результату
 Передбачається, що змінні, описані як результати, будуть параметрами-змінними "повернуть" необхідні значення в основну програму
         
 Повернення результату забезпечується командоюНазва_функціїї : = результат
Перед тим, як написати програми цілком, розглянемо алгоритми основних частин.
                                     Алгоритм, що використовує підпрограму-функцію
алг
  Snake (ціл k, n, ціл kil)
        арг  k, n
        рез  kil
поч
      kil : = Факторіал(n)/Факторіал(n - k)
кін
Зверніть увагу на те, що: 1) функцію ми викликаємо прямо з описаного виразу;
2) для виклику функції певній змінній присвоюють значення або самої функції, або виразу, що містить виклик функції або кількох функцій (як у нашому прикладі).
                                    Алгоритм, що використовує підпрограму-процедуру
алг Snake (ціл k, n, ціл kil)
       арг  k, n
       рез  kil
поч
      ціл kil1, kil2
     Факторіал (n, kil1)
     Факторіал (n - k, kil2)
     кil : = kil1/kil2
кін

Зверніть увагу на те, що вписати процедуру до складу виразу ми не можемо. Ми спочатку викликаємо процедуру для фактичного параметра n (результат вписується в змінну kil1), потім для n - k (результат повертається в kil2). І лише потім описуємо формулу для необхідних обчислень.
Розглянемо повністю 2 програми, одна з яких містить процедуру, а друга - функцію.
Program Snake;
    Uses Crt;
    Var
          k, n : integer;
          kil, kil1, kil2 : longint;
     procedure Faktorial (p : integer, Var rez : longint);
        Var
              i : integer;
     begin
           rez : = 1;
           for i : =1 to p do
           begin
                 rez : = rez * i;
           end;
    end;
BEGIN
       Write(‘k, n =>');
        Readln(k, n);
       Faktorial(n, kil1);
       Faktorial (n - k, kil2);
       kil : = trunc(kil1/kil2);
       Write(‘kil=', kil);
       Readkey;
END.
Примітка. Кількість шуканих номерів буде цілим числом. Але результат ділення в Pascal - це завжди число дійсне (навіть 4 - це 4.0). Тому ми використовуємо функцію trunс для відкидання дробової частини (яка у нас .0000) і отримання цілого результату.
Program Snake;
    Uses Crt;
    Var
         k, n : integer;
         kil : longint;
    function Faktorial (p:integer):longint;
       Var
             i : integer;
             rez : longint;
    begin
          rez : = 1;
          for  i : =1 to p do
          begin
               rez : = rez * i;
          end;
          Faktorial : =  rez;
     end;
BEGIN
       ClrScr;
       Write(‘k, n =>');
       Readln(k, n);
       kil : = trunc(Faktorial(n)/Faktorial (n - k));
       Write(‘kil= ', kil);
       Readkey;
END.

Задача
 Дано 2 натуральні числа a i n. Обчислення піднесення до степеня an оформити як функцію.
Розв'язання
Зрозуміло, що для піднесення a до степеня n, потрібно n раз помножити число a.
                                       Допоміжний алгоритм (функція)
алг
 ціл Степінь (ціл osn, st, ціл rez)
        арг  osn, st
        рез  rez
поч
      ціл і
      і : = 1
      rez : = 1
      для  і  від 1 до st
      пц
            rez : =  rez * osn
      кц
      знач : = rez
кін

Примітка. Змінні a i n, задані в умові, є глобальними фактичними параметрами, а в функції формальні параметри ми називаємо по-іншому.

                                          Алгоритм основної програми
алг Обчислення_степеня (ціл a, n, ціл r)
       арг a, n
       рез r
поч
      r : = Степінь (a, n)
кін

1. Сконструюйте із запропонованих фрагментів функцію Степінь, вказавши порядок кроків за зразком:123456789.
     1)       Stepin : = rez;
        end;
     2) rez : longint;
     3) for  i : =1 to st do
     4) begin
              rez : = 1;
     5) function Stepin (osn, st : integer) : longint;
     6) begin
     7) Var
              i : integer;
     8)  rez : =  rez * a;
     9) end;
 

                            Програма піднесення до степеня з використанням функції
Program Obch_Stepin;
     Uses Crt;
     Var
          a, n : integer;
          r : longint;
      function Stepin (osn, st : integer) : longint;
         Var
              i : integer;
              rez : longint;
      begin
            rez : = 1;
            for  i : =1 to st do
            begin
                 rez : = rez * a;
            end;
           Stepin : = rez;
      end;
BEGIN
       ClrScr;
       Write(‘a, n =>');
       Readln(a, n);
       r : = Stepin(a, n);
       Write(‘r= ', r);
       Readkey;
END.

2. У фрагменті програми
     Var
            x, y, z : integer;
            a : real;
      function f1(m, n : integer) : real;
        Var
             p, r : integer;
             s : real;
      begin
               . . .
      end; 
змінні m, n є для функції:
1) глобальними, фактичними;
2) глобальними, формальними;
3) локальними, формальними;
4) локальними, фактичними.
3. Які з вказаних команд забезпечують коректне звернення до функції
        function Syma (a, b : integer) : integer?
     1) m : = Syma(4, 12) + 2*Syma(45, -23);
     2) f : = Syma(23, 6.78);
     3) c : = 45;  rez : = Syma (2, 3*c);
     4) Syma (3, 67).
Введіть відповідь за зразком: 3, або 12, або 234 (цифри у порядку зростання).
 
4. Оберіть ті характеристики, які стосуються функції:
1) у заголовку описуються лише аргументи;
2) у заголовку описуються і аргументи, і результати;
3) не може входити до складу виразів;
4) повернення результатів в алгоритмічній мові здійснюється за допомогою службового слова “знач”;
5) може входити до складу виразів;
6) повернення результатів на Pascal здійснюється присвоєнням імені функції обчисленого результату;
7) повернення результатів на Pascal здійснюється за допомогою службового слова Var.
5. Дано фрагмент програми:
    function  Dobytok (a, b : integer) : integer;
      Var
           d : intger;
   begin
         d : = a * b;
   end;
         . . .
   rez : = Dobytok(7, 9);
         . . .
Якого значення набуде змінна rez?
 
6. Дано фрагмент програми:
   Var
        x, y, z : real;
   function F1 (a, b : integer) : real;
   begin
           F1 : = a / b;
   end;
       . . .
   k : = 9.1;
   rez : = F1(k, 7);
       . . .
При компілюванні буде виникати помилка через:
1) неправильне звернення до функції;
2) невідповідність кількості формальних та фактичних параметрів;
3) невідповідність типів формальних та фактичних параметрів;
4) помилку в заголовку функції.
7. Дано заголовки алгоритмів. Які з них при перекладі на Pascal оформлятимуться як функції?


1) алг ціл Обчислення1;
2) алг Обчислення2;
3) алг дійсн Обчислення3 (ціл х, у);
4) алг Обчислення4 (ціл a, b, дійсн d).

Немає коментарів:

Дописати коментар