[ЗМІСТ]      [Далі]       [Назад]      [Початок розділу]

 

7.10 Процедурний тип даних

 

      Описи процедур та функцій у алгоритмах, які ми розглядали у розділі 6, можна вважати визначенням констант деякого типу. Цей тип ми будемо називати процедурним, а окрім констант, визначимо також змінні процедурного типу. Змінні процедурного типу зручно застосовувати у випадках, коли заздалегідь невідомо, яка саме процедура або функція повинна бути викликана, наприклад, при обчисленні деякого функціоналу.

      Процедурний тип даних будемо позначати:

 

 

тип tpf = функція (t1; t2; ...; tn): t;

 

 

або

 

 

тип tpf = процедура (арг t1; t2; ...; tn; мод s1; s2; ...; sm; рез r1; r2; ...; rk);

 

 

де t1, t2, ..., tn – типи аргументів, s1, s2, ..., sm – типи модифікованих параметрів, r1, r2, ..., rk – типи результатів, t – тип результату функції.

      Змінні процедурного типу будемо описувати як звичайні змінні:

 

      змін P, Q: tpf;

 

      Область типу tpf - Dtpf визначається як об’єднання множин:

 

      Dtpf = Mp È Mf,

 

де Mp = { t1, t2, ..., tn, s1, s2, ..., sm -> s1, s2, ..., sm, r1, r2, ..., rk} – множина всіх відображень декартового добутку областей типів t1, t2, ..., tn, s1, s2, ..., sm у декартів добуток областей типів s1, s2, ..., sm, r1, r2, ..., rk,

 

а Mf = { t1, t2, ..., tn -> t} – множина всіх функцій з декартового добутку областей типів t1, t2, ..., tn у область типу t.

 

      На процедурному типі даних визначено операцію виклику процедури або функції. Наприклад, для описаної раніше змінної P

 

      P(e1, e2, ..., en, v1, v2, ..., vm, w1, w2, ..., wk)

 

(звичайно, спочатку треба присвоїти P значення деякої процедури типу tpf. З відношень визначаються тільки = та <>, а з інструкцій – тільки присвоєння.

 

      Приклад 7.19. Обчислення інтеграла функції f(x) на відрізку [a,b] методом трапецій.

      Розв’язок. При обчисленні інтеграла методом трапецій відрізок [a,b] поділяється на n відрізків однакової довжини точками x0 = a, x1, ..., xn = b. На кожному відрізку [xi,xi+1] обчислюється площа трапеції ABCD, де A=xi, B=f(xi), C=f(xi+1), D= xi+1. Ця площа обчислюється за формулою: (f(xi)+f(xi+1))*(xi+1-xi)/2 (у випадку, коли функція f на відрізку [xi,xi+1] змінює знак, обчислення виконується за цією ж формулою). Інтеграл на відрізку [a,b] обчислюється як сума площ всіх трапецій.

      Будемо обчислювати інтеграл S по кроках. На першому кроці n=1. На кожному наступному кроці будемо збільшувати n вдвічі. Обчислення завершимо на j-му кроці, якщо |SjSj-1| < e, де Sj – інтеграл на j-му кроці, Sj-1 – інтеграл на (j-1)-му кроці e>0 – задане число. Отримуємо алгоритм:

 

    тип MathFunc = функція (дійсн): дійсн;

        ...........................

{опис програмованої функції для обчислення f(x)}

        ...........................

    функція Integral (F: MathFunc; A, B, EPS: дійсн): дійсн це

       змін X, Y, Y1, S, S1, H: дійсн;

            N, I: нат;

    поч

       N <- 1; H <- B-A;

       S <- (F(B)+F(A))*H/2;

       повт

          N <- N*2; H:= (B-A)/N;

          S1 <- S; S <- 0;

          X <- A; Y1 <- F(X);

          для I <- 1 до N повт

             Y <- Y1;

             X <- A+H*I; Y1 <- F(X);

             S <- S+(Y+Y1)*H/2

          кц;

       до abs(S-S1)<EPS;

       Integral <- S

    кф.

 

      У мові Паскаль процедурний тип описують:

 

      type tpf = function (x1: t1; x2: t2; ...; xn: tn): t;

 

або

 

      type tpf = procedure (x1: t1; x2: t2; ...; xn: tn

                  var y1: s1; var y2: s2; ...; var ym: sm);

 

де x1, x2, ..., xn – аргументи; t1, t2, ..., tn – їх типи; y1, y2, ..., ym – параметри-змінні; s1, s2, ..., sm – їх типи; t – тип результату функції.

      Приклади описів:

 

  type

    Proc = procedure;

    SwapProc = procedure(var X, Y: Integer);

    StrProc = procedure(S: string);

    MathFunc = function(X: Real): Real;

    DeviceFunc = function(var F: text): Integer;

    MaxFunc = function(A, B: Real; F: MathFunc): Real;

 

Опис змінних процедурного типу:

 

      var P: Proc; F: MathFunc;

 

Для процедурного типу даних у Паскалі визначено виклик та присвоєння. Відношення не визначені. Змінні процедурного типу можна також передавати як параметри підпрограм.

      Примітка: Для використання процедурного типу даних у програмі на Паскалі обов’язково треба вказати на початку програми опцію компілятора {$F+}.

 

      Приклад 9P. Обчислення інтеграла функції f(x) на відрізку [a,b] методом трапецій (задача 7.19). В якості функції розглянемо поліном f(x)=x3-7x-1.

 

{$F+}

  Program TrapecInt;

    type MathFunc = function(X: real): real;

 

    function Poly(X: real):real;

      begin

        Poly:=x*x*x-7*x-1

      end;

 

    function Integral (F: MathFunc; A, B, Eps: real): real;

       var X, Y, Y1, S, S1, H: real;

            N, I: word;

    begin

       N := 1; H := B-A;

       S := (F(B)+F(A))*H/2;

       repeat

          N := N*2; H:= (B-A)/N;

          S1 := S; S := 0;

          X := A; Y1 := F(X);

          for I := 1 to N do begin

             Y := Y1;

             X := A+H*I; Y1 := F(X);

             S := S+(Y+Y1)*H/2

          end;

       until abs(S-S1)<Eps;

       Integral := S

    end;

 

    var A, B, Eps, S: real;

    begin

      write(‘Введіть границі відрізку [a,b]: ’); readln(A,B);

      write(‘Введіть eps: ’); readln(Eps);

      S:=Integral(Poly, A, B, Eps);

      writeln(‘Інтеграл дорівнює ’, S)

    end.

 

      У мові Сі процедурний тип даних реалізується з використанням вказівників на функції. Вказівник на функцію Сі – це змінна, значенням якої є початкова адреса функції. Вказівнику на функцію можна присвоїти значення функції того ж типу, який має вказівник, а також використати вказівник на функцію як параметр підпрограми. Для вказівників на функції визначено також відношення: == та !=. Загальний вигляд опису:

 

      t (*name)(t1, t2, ..., tn);

 

де nameім’я вказівника на функцію; t – тип результату функції; t1, t2, ..., tn – типи параметрів функції. Для функцій Сі, що не повертають значення та є реалізацією процедур, для типу t використовують ідентифікатор void, що означає „будь-який тип”. Позначення *name обов’язково брати в дужки, бо інакше воно буде інтерпретовано як „функція, що повертає результат типу вказівника на тип t.

 

      Приклади описів:

 

    typedef double (*math_func)(double);

 

    void (*proc)();

    void (*swap_proc)(int *, int *);

    void (*str_proc)(char *);

    math_func f;

 

      Приклад 9С. Обчислення інтеграла функції f(x) на відрізку [a,b] методом трапецій (задача 7.19). В якості функції розглянемо поліном f(x)=x3-7x-1.

 

#include <stdio.h>

#include <math.h>

 

/* TrapecInt */

 

typedef double (*math_func)(double);

 

double polynm(double x)

{

  return x*x*x-7*x-1;

}

 

double integral (math_func f, double a, double b, double eps)

{

  double x, y, y1, s, s1, h;

  unsigned n, i;

 

  n = 1; h = b-a;

  s = (f(b)+f(a))*h/2;

  do

    {

     n *= 2; h = (b-a)/n;

     s1 = s; s = 0;

     x = a; y1 = f(x);

     for (i=1; i<=n; i++)

       {

        y = y1;

        x = a+h*i; y1 = f(x);

        s += (y+y1)*h/2;

       }

    }

  while (fabs(s-s1)>=eps);

  return s;

}

 

main()

{

  double a, b, eps, s;

 

  printf(“Введіть границі відрізку [a,b]: ”);

  scanf(“%lf %lf”, &a, &b);

  printf(“Введіть eps: ”); scanf(“%lf”, &eps);

  s=integral(polynm, a, b, eps);

  printf(“Інтеграл дорівнює %lf\n”, s);

}

 

Задачі та вправи

 

      Вправа 7.3. Визначити програмовану функцію для доповнення множини.

 

      Вправа 7.4. Визначити процедуру введення числової множини.

 

      Вправа 7.5. Визначити функцію, що дає мінімальний елемент числової множини.

 

      Вправа 7.6. Показати елементи числової множини в порядку зростання.

 

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

 

      Вправа 7.8. Діаметром числової множини називається величина

 

       d(А) =   max   ¦x-y¦.

              х, у Î А

 

Визначити функцію обчислення діаметра d(А).

 

      Вправа 7.9. Визначити процедуру отримання

      a) мінімального;

      b) максимального

елемента множини.

 

      Вправа 7.10. Нехай Q(х) - умова. Визначити функцію, що дає по множині А підмножину всіх таких її елементів, для яких справедлива умова Q(х).

 

      Вправа 7.11. Визначити програмовані функції для різниці, добутку та частки двох комплексних чисел.

 

      Вправа 7.12. Визначити програмовані функції для обчислення модуля та аргументу комплексного числа.

 

      Вправа 7.13. Визначити програмовану функцію степені комплексного числа з натуральним показником.

 

      Вправа 7.14. Визначити тип "комплексне число в тригонометричній формі" та підпрограми для операцій та інструкцій з прикладу 7.5 та вправ 7.11 і 7.13.

 

      Вправа 7.15. Визначити функцію переведення комплексного числа з алгебраїчної у тригонометричну форму та навпаки.

 

      Вправа 7.16. Визначити функцію дати вчорашнього дня.

 

      Вправа 7.17. Визначити функцію обчислення дня тижня по його даті в поточному році.

 

      Вправа 7.18. Визначити інші функції для універсального комплексного типу. Для двомісних операцій передбачити всі можливі випадки.

 

      Вправа 7.19. Визначити тип плоска фігура, що включає трикутник, паралелограм, трапецію та коло. Побудувати функції обчислення периметра та площі плоских фігур.

 

      Вправа 7.20. Визначити процедури для

      а) введення;

      b) виведення

елементів дійсного вектора.

 

      Вправа 7.21. Визначити функції обчислення

      а) норми дійсного вектора;

      b) скалярного добутку двох дійсних векторів.

 

      Вправа 7.22. Визначити функції для обчислення значення

      а) похідної в заданій точці;

      b) інтеграла на заданому відрізку

многочлена з прикладу 7.10.

 

      Вправа 7.23. Визначити функцію обчислення k-ої похідної многочлена з прикладу 7.10.

 

      Вправа 7.24. Циклічним k-зсувом вектора (а1, ..., аn) ліворуч називається вектор (аk+1, ..., аn, а1, ..., аk). Визначити функцію для його обчислення.

 

      Вправа 7.25. Визначити циклічний k-зсув праворуч і функцію для його обчислення.

 

      Вправа 7.26. Визначити процедуру пошуку в двовимірній таблиці.

 

      Вправа 7.27. Визначити процедуру пошуку

      а) максимальної;

      b) мінімальної

компоненти вектора.

 

      Вправа 7.28. Визначити процедуру пошуку спільної компоненти двох векторів.

 

      Вправа 7.29. Визначити процедуру пошуку спільної компоненти двох впорядкованих векторів. (Вектор (а1, ..., аn) впорядкований, якщо а1 < ... < аn.

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

 

      Вправа 7.31. Файл F типу файл із t; (описаний у (7.6)) називається впорядкованим по ключах, якщо записи в ньому розташовані в порядку зростання ключів. Визначити процедуру пошуку запису по ключу у впорядкованому файлі.

 

      Вправа 7.32. Визначити підпрограму перевірки рівності файлів, що виконується за один перегляд їх вмісту.

 

      Вправа 7.33. Визначити процедуру видалення з файла запису з заданим ключем.

 

      Вправа 7.34. Визначити процедуру видалення з впорядкованого файла запису із заданим ключем.

 

      Вправа 7.35. Слова у текстовому файлі F розділяються одним або декількома пропусками. Переписати файл F у файл G так, щоб між словами залишилося по одному пропуску.

 

      Вправа 7.36. Визначити підпрограму для обчислення кореня неперервної монотонної функції f(x) на відрізку [a,b] методом ділення відрізку навпіл, якщо відомо, що функція на цьому відрізку змінює знак.

 

[ЗМІСТ]      [Далі]       [Назад]      [Початок розділу]