У наведеному прикладі k є формальним параметром-аргументом, с — формальним параметром-результатом.
Підпрограми Підпрограми призначені для реалізації алгоритмів опрацювання окремих частин деякої складної задачі. Вони дають змогу реалізовувати концепцію структурного програмування, суть якого полягає в розкладанні складної задачі на послідовність простих підзадач і в складанні для алгоритмів розв’язування кожної підзадачі відповідних підпрограм. Розрізняють два види підпрограм — підпрограми-процедури та підпрограми-функції. Підпрограми поділяються на стандартні та підпрограми користувача. Стандартні підпрограми створювати не потрібно — вони містяться у стандартних модулях System, Crt, Dos, Graph тощо. Підпрограма користувача — це пойменована група команд, яку створюють і описують в основній програмі в розділах procedure або function і до якої звертаються з будь-якого місця програми потрібну кількість разів. 1. Процедури (procedure). Загальний опис процедури:
У списку формальних параметрів перераховують змінні разом із зазначенням їхніх типів. Розрізняють параметри-аргументи (інший термін: параметри-значення) — вхідні дані для процедури, і параметри-результати (інший термін: параметри-змінні), через які можна повертати результати роботи процедури в основну програму. Перед списками параметрів-результатів кожного типу записують слово var. Зауважимо, що масиви фіксованих розмірів у списках формальних параметрів не можна описувати за допомогою слова array (див. зразки програм). Розділи описів і оголошень у підпрограмах мають таку саму структуру як і в основній програмі.
Приклад. Розглянемо процедуру з назвою Cina, яка визначає с —вартість k хвилин телефонної розмови з похвилинною оплатою 0.6 грн. + 20% ПДВ. procedure Cina(k:integer; var c:real); Begin c:=k*0.6; c:=c+0.2*c; end; У наведеному прикладі k є формальним параметром-аргументом, с — формальним параметром-результатом. До процедури звертаються з розділу команд основної програми або іншої підпрограми. Процедуру викликають за допомогою команди виклику:
Параметри, які записують у команді виклику процедури, називаються фактичними. Фактичними параметрами-аргументами можуть бути сталі, змінні, вирази, а параметрами-результатами — лише змінні. Типи даних тут не зазначають. Між фактичними і формальними параметрами має бути відповідність за кількістю й типами. Зверніть увагу, відповідні фактичні та формальні параметри можуть мати різні імена. Команда виклику функціонує так: значення фактичних параметрів присвоюються відповідним формальним параметрам процедури, виконується процедура, визначаються параметри-результати, значення яких надаються (повертаються) відповідним фактичним параметрам у команді виклику. Змінні, описані в розділі описів основної програми, називаються глобальними. Вони діють у всіх підпрограмах, з яких складається програма. Змінні, описані в розділі описів конкретної процедури, називаються локальними. Вони діють тільки в межах даної процедури. Процедури можуть отримувати і повертати значення не тільки через параметри-результати, але й через глобальні змінні. Тому списків параметрів у процедурі може і не бути. Задача 1. Розв’язати задачу про кількість викликів на АТС з попереднього параграфа, використовуючи три процедури: 1) для визначення кількості викликів за кожну секунду (надамо їй назву Kilvykl); 2) для обчислення суми викликів за перші 10 секунд (Sumavykl); 3) для визначення найбільшої кількості викликів за деяку секунду (Maxkilvykl). Використати функцію random.
program ATS1; uses Crt; type vyklyk= array [1..10] of integer; var y:vyklyk; max, s:integer; procedure Kilvykl(var y:vyklyk); { Процедура Kilvykl визначає } var i:integer; { кількість викликів кожної секунди } Begin for i:=1 to 10 do Begin y[i]:=random(i); writeln('y(', i, ')=', y[i]:5); end; end; procedure Sumavykl(y:vyklyk; var s:integer); { Процедура обчислює cуму викликів за перші 10 секунд } var i:integer; Begin s:=0; for i:=1 to 10 do s:=s+y[i]; writeln('Сума викликів S=', s:3); end; procedure Maxkilvykl(y:vyklyk; var max:integer); var i:integer; { Процедура Maxkilvykl визначає } begin { найбільшу кількість викликів} max:=y[1]; { за деяку секунду} for i:=2 to 10 do if max<y[i] then max:=y[i]; write('Максимальна кількість викликів за одну '); writeln('секунду дорівнює ', max:3) end; Begin clrscr; randomize; Kilvykl(y); { Виклик процедури Kilvykl} Sumavykl(y, s); { Виклик процедури Sumavykl} Maxkilvykl(y, max); { Виклик процедури Maxkilvykl} readln End. 2. Функції (function). Функція, на відміну від процедури, може повертати в місце виклику лише один результат простого стандартного типу. Загальний опис функції:
У розділі команд функції має бути команда присвоєння значення деякого виразу назві функції. Результат функції повертається в основну програму через її назву (як і випадку використання стандартних функцій, таких як sin, cos). Виклик функції здійснюється лише з виразів так:
Приклад. Створимо функцію для обчислення tg(x) та обчислимо значення виразу tg(x)+ctg(x)+tg2(x). program Myfunc; uses Crt; var x,y:real; function tg(x:real):real; Begin tg:=sin(x)/cos(x) end; begin clrscr; writeln('Введіть х'); readln(x); y:=tg(x)+1/tg(x)+sqr(tg(x)); writeln('y=', y:5:2); readln End. Задача 2. Розв’язати задачу про виробництво цукерок на фабриці з попереднього параграфа, використовуючи функції і процедури користувача. program Fabryka1; uses Crt; const n=5; type vytraty = array [1..n, 1..n] of real; var imin:integer; a:vytraty; function func(i,j:integer):real; Begin func:=2*abs(sin(i))+j; end; procedure Table(var a:vytraty); var i,j:integer; Begin writeln(' Вид сировини'); writeln(' 1 2 3 4 5'); for i:=1 to n do {Утворимо таблицю затрат} Begin write(i, ' сорт'); for j:=1 to n do Begin a[i,j]:=func(i,j); {Використаємо створену функцію}
write(a[i,j]:7:2); {Роздрукуємо елементи і-го рядка} end; writeln {Перейдемо на новий рядок} end; end; procedure MinSyrov(a:vytraty; var imin:integer); var i,j:integer; min:real; Begin imin:=1; min:=a[1,3]; for i:=2 to n do if a[i,3]<min then Begin min:=a[i,3]; imin:=i end; writeln('Найменше сировини третього виду '); writeln('необхідно для цукерок ', imin, ' сорту') end; Begin clrscr; Table(a); {Виклик процедури Table } MinSyrov(a, imin); {Виклик процедури MinSyrov } readln End. 3. Рекурсивні функції. Рекурсією називається алгоритмічна конструкція, де підпрограма викликає сама себе. Рекурсія дає змогу записувати циклічний алгоритм, не використовуючи команду циклу. Розглянемо спочатку поняття стеку. Стек — це структура даних в оперативної пам’яті, де дані запам’ятовуються і зберігаються за принципом «перший прийшов — останнім пішов». Аналогом у військовій справі є ріжок для набоїв до автомата. Приклад. Рекурсивна функція обчислення суми цілих чисел від a до b має вигляд function Suma(a,b:integer):integer; Begin if a=b then Suma:= a { Це стоп-умова рекурсії } else Suma:= b + Suma(a, b–1) { Це неявний цикл } end; Обчислимо функцію Suma(3, 5). Формально можна записати Suma(3, 5) = 5 + Suma(3, 4) = 5 + 4 + Suma(3, 3) = 5 + 4 + 3. Система виконує такі обчислення за два етапи: 1) спочатку формує стек, куди заносить числа 5, 4, 3. На другому етапі числа додає у зворотній послідовності (оскільки вони надходять зі стеку): 3+4+5 = 12. Задача 3. Скласти рекурсивну функцiю Factorial для обчислення факторіала числа n! = 1·2·3·...· n, (0! = 1, 1! = 1), яка грунтується на багаторазовому (рекурсивному) застосуваннi формули n! = n ·(n – 1)!. function Factorial(n: integer): integer; Begin if n = 0 then Factorial:= 1 { Це стоп-умова } else Factorial:= n * Factorial(n–1) end; Обчислимо 4!: Factorial(4) = 4 · Factorial(3) = 4 · 3 · Factorial(2) = 4 · 3 · 2 · Factorial(1) = 4 · 3 · 2 · 1 · Factorial(0) = 4 · 3 · 2 · 1 · 1. У стек будуть занесені числа 4, 3, 2, 1, 1. Результат утвориться так: 1 · 1 · 2 · 3 · 4 = 24. Зауваження. Застосовуючи рекурсію, потрібно правильно складати стоп-умови, які забезпечують закінчення циклічних обчислень. Завдання 3. Скласти програму розв’язування задачі 6, використовуючи рекурсивні функції. 4. Відкриті масиви. У списках формальних параметрів підпрограми можна описувати так звані відкриті масиви (масиви заздалегідь невідомого розміру) так:
У підпрограмі мінімальне значення індекса такого масиву є 0, а номер останнього елемента дає стандартна функція high (<назва масиву>). Нумерація елементів такого формального масиву у підпрограмі починається з нуля. Відкритий масив використовують для почергового опрацювання у процедурі масивів різних розмірів. Задача 4. Використовуючи підпрограми, утворити масив y, елементи якого задані формулою ут = fy (m)=10cos(m)+2, , та масив g з елементами gn=fg (n) =n 2/2, . Обчислити в цих масивах суми елементів більших, ніж 2. Вивести на екран результати обчислень. program MyProcedure; {$F+} uses Crt; type myfunc= function (n:integer):real; var y: array [1..7] of real; g: array [1..9] of real; function fy(m:integer):real; Begin y:=10*cos(m)+2 end; function fg(n:integer):real; Begin g:=n*n/2 end; procedure Utvoryty(f:myfunc; var z: array of real); var i:integer; Begin for i:=0 to high (z) do Begin z[i]:=f(i+1); write(z[i]:5:2); end; writeln end; function suma(z: array of real):real; var i:integer; s: real; Begin s:=0; for i:=0 to high (z) do if z[i]>2 then s:=s+z[i]; suma:=s end; Begin clrscr; Utvoryty(fy, y); Utvoryty(fg, g); write('Сума потрібних елементів y – '); writeln('S=', suma(y):6:2); write('Сума потрібних елементів g – '); writeln('S=', suma(g):6:2); readln End. Зауваження. Зверніть увагу на утворення та застосування нового типу – типу функції: type myfunc= function (n:integer):real. До цього типу віднесено конкретні функції fy (x) та fg (x). Завдяки типу myfunc можна за допомогою однієї процедури утворювати різні масиви. У зв'язку з цим використано директиву {$F+}, яка підтримує необхідну модель (far-модель) виклику функцій. 5. Стандартні модулі. Підпрограми, які мають універсальне призначення та можуть згодитись багатьом користувачам, варто об’єднувати у бібліотеки та модулі. Модуль — незалежна програмна одиниця. Він містить описи констант, типів даних, змінних та підпрограм. Розрізняють стандартні модулі та модулі, створені користувачем. Є такі стандартні модулі:
Під’єднання модулів у конкретній програмі здійснюють за допомогою команди
Процедури і функції модуля System можна застосовувати за замовчуванням. Саме з цього модуля компілятор бере процедури read, readln, write, writeln, стандартні функції sin, cos тощо. Розглянемо по чотири корисні процедури з модулів System та Crt:
З-поміж функцій модуля Crt часто застосовують символьну функцію readkey, яка отримує значення натиснутого користувачем символу на основній символьно-цифровій частині клавіатури, а також логічну функцію keypressed, яка набуде значення true, якщо користувач натисне на будь-яку клавішу на основній клавіатурі. У модулі Dos є процедури і функції для роботи з файловою системою в режимі виконання паскаль-програми. Процедура exec ('<повна назва exe-файлу>', '<параметри програми>' або '') служить для запуску на виконання exe-файлу іншої програми з середини програми користувача (на початку програми користувача слід зазначити директиву {$M $2000,0,1000}, див. довідники). Корисними є також дві процедури, які дають змогу хронометрувати час виконання програми користувача чи її фрагментів і опрацьовувати дати: GetTime (Hour, Minute, Second, SotiSec) — надає зазначеним у списку змінним числові значення поточного часу (год, хв, сек, соті сек); GetDate (Year, Month, Day, Number) — надає змінним зі списку типу word значення поточної дати(рік, місяць, день, день тижня). Завдання 5. Розгляньте завдання № 3 з § 5 про обчислення знакозмінної суми трьома способами з точністю e =0,00001 (§ 5, п.2, задача-зразок № 4, власна задача-завдання № 7 з розділу "Задачі"). Зробіть exe-файли для відповідних трьох програм. Складіть програму, яка буде складатися з директиви {$M...}, команди uses Crt, Dos; трьох команд типу exec('suma1.exe', ''); декількох команд gettime(...), розташованих так, щоб хронометрувати час виконання процесором кожної з під’єднаних програм. Визначіть час у мікросекундах, затрачений процесором для розв’язування задачі кожним способом. Який спосіб найефективніший за часом обчислень? 6. Модулі користувача (unit). Свій модуль користувач будує за певними правилами. Структура модуля така:
Назву модулю дає користувач. Вона має бути унікальною. У розділі описів оголошують інші потрібні модулі, описують типи, сталі та заголовки підпрограм, доступні у даному модулі. У реалізаційній частині наводять тексти підпрограм за порядком згадування їхніх заголовків у описах. Списки параметрів можна не писати, оскільки вони наведені в описах заголовків. Інтерфейс і реалізаційна частина можуть бути порожніми. Таку можливість використовують, коли необхідно описати, наприклад, спільні для багатьох програм сталі, змінні, типи даних. У блоці ініціалізації у разі потреби задають початкові дані, відкривають файли, чистять екран тощо. Цей блок виконується першим, тобто перед командами основного блоку головної програми, до якої приєднаний даний модуль. Якщо стартовий блок не потрібний, то службове слово begin опускають. Модулі використовуються, зокрема, у візуальному програмуванні (див. розділ 3). Приклад. Створимо модуль для обчислення значень функцій tg(x), xy . Під час звертання до нього очистимо екран. unit Mymodul; Interface uses Crt; function tg(x:real):real; function step(x,y:real):real; Implementation function tg(x:real):real; Begin tg:=sin(x)/cos(x) end; function step(x,y:real):real; Begin step:=exp(y*ln(x)) end; begin clrscr End. Щоб оформити підпрограму як модуль в меню середовища Турбо Паскаль в пункті Compile/Destination встановлюємо значення Disk і транслюємо її (Ctrl+F9). На диску отримаємо файл з тим же іменем, але з розширенням tpu. Модуль створено. Приклад. Обчислимо tg(x) і 1.35, використовуючи модуль Mymodul. program UseModul; uses Mymodul; var x,y,a,b,c:real; Begin a:=1.3; b:=5; writeln('Введіть x:'); readln(x); y:=tg(x); writeln('tg(', x:5:2,')=', y:6:2); c:=step(a, b); writeln('1.3^5=', c:5:2); readln End. Окремі модулі користувач може об’єднати в особисту бібліотеку (наприклад Mybibl.tpl) за допомогою програми TpuMover, виконавши в середовищі MS-DOS команду tpumover <повний шлях до файлу>\Mybibl.tpl /+ Mymodul Зауваження. Файл Mybibl.tpl необхідно розташувати в каталозі, де немає файла з системною бібліотекою turbo.tpl.
Читайте также: Актуальні проблеми глобалізації (на прикладі розвинутих країн та країн, що розвиваються) Воспользуйтесь поиском по сайту: ©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|