Тема уроку: "Розв'язування задач на складання алгоритмів з використанням процедур"

Мета уроку: Дати поняття про допоміжні алгоритми, типи допоміжний алгоритмів, оформлення підпрограм (процедур) мовою програмування Паскаль.
Тип уроку: Практичний.

На початку уроку рекомендується провести опитування у письмовому чи усному вигляді для закріплення теоретичного матеріалу попереднього уроку (поняття допоміжного алгоритму, типи допоміжних алгоритмів, передача параметрів у допоміжний алгоритм, локальні та глобальні, фактичні та формальні параметри тощо).
Після цього рекомендується розв'язати з учнями кілька задач.

Задача № 417.
Умова: Баба-Яга записалася на курси водіїв літальних апаратів. Але справи в неї були кепські, бо вона ніяк не могла запам'ятати, яким чином визначається тривалість польоту, якщо відомі швидкість і відстань. Довелося їй звернутися по допомогу до Хлопчика-Мізинчика, який швиденько написав їй шпаргалку, куди Бабі-Язі треба було лише підставити свої значення. Як виглядала послідовність дій у цій шпаргалці і як нею користувалася Баба-Яга?
Очевидно, що "шпаргалку" Хлопчика-Мізинчика можна оформити як допоміжний алгоритм. Параметрами, що передаються в цей алгоритм, будуть швидкість літального апарату та відстань, яку необхідно подолати, а вихідним параметром - шукана тривалість польоту. Вхідні параметри процедури повинні бути параметрами-значеннями, а вихідний параметр - параметром-змінною (дивись матеріал попереднього уроку).
Позначимо у підпрограмі формальні параметри наступним чином:
V - швидкість літального апарату;
S - відстань, що необхідно подолати;
T - тривалість польоту.
В основній програмі ті ж самі змінні будуть мати відповідно імена: X, Y та M (імена змінних у основній програмі бажано, щоб не співпадали з іменами локальних параметрів підпрограми, тому їх вибір являється випадковим).
Спробуємо на цьому уроці оформити допоміжний алгоритм, як процедуру. Тоді вихідна програма буде мати наступний вигляд:

 Program Example_417; 
Uses crt; {Підключення бібліотеки} 
Procedure Solution (V,S - real; var T - time); 
Begin 
T:=S/V; 
End; 
Var X,Y,M:real; 
Begin 
Clrscr; 
Write('Введіть швидкість літального апарату: '); 
Readln(X); 
Write('Введіть відстань між населеними пунктами: '); 
Readln(Y); 
If (X<=0) or (Y<0)  
then writeln('Некоректні вхідні дані.') 
else 
begin 
Solution(X,Y,M); {Виклик процедури} 
Writeln('Тривалість польоту -> ',M:6:2); 
end; 
Readkey; 
End. 

Задача № 423 (модифікована).
Умова: У Білосніжки наближався день народження і її вирішили привітати друзі. Перш за все це були гноми, далі зібралися звірята, а потім і пташки прилетіли. Кожен з гостей приніс квіти, кількість яких зберігається у відповідному масиві: а1, а2, ... an - квіти гномів, b1, b2, … bm - квіти звірят та c1, c2, …, ck - квіти пташок. Хто з гостей (гноми, звірята чи пташки) приніс найбільшу кількість квітів? Який з гномів, звірят та пташок найщедріший?
Так як підпрограма в даному випадку повинна обчислити два значення (загальну кількість квітів, що принесли гноми, звірята та пташки відповідно, та максимальну кількість квітів, принесену одним з персонажів), то підпрограму зручно оформити процедурою. Вхідним параметром в цьому випадку буде масив, який містить кількість квітів, що принесли персонажі, та кількість елементів масиву (кількість відповідно гномів, звірят та пташок, що були на дні народження), а вихідними параметрами - загальна кількість квітів по кожному з "різновидів" гостей (сума всіх елементів масиву) та кількість квітів від самого щедрого персонажу (максимальний елемент масиву). Очевидно, що вхідні параметри будуть параметрами-значеннями, а вихідні - параметрами-змінними.
Позначимо масив, що підлягає обробці, MAS, кількість елементів масиву count, а відповідні значення суми елементів масиву та максимум SUM та MAX.
Зверніть також увагу на те, що всі три масиви необхідно заповнити початковими значеннями і щоб не повторювати однакові фрагменти в програмі, напишемо ще одну процедуру INPUT, що буде заповнювати масив M заданою кількістю елементів count.
Зверніть увагу учнів на те, що в даній програмі формальним параметром процедури являється масив. Відмітимо, що в списку формальних параметрів може бути тільки стандартний або раніше визначений тип. Тому не можна описати наступну процедуру таким чином:

Procedure S (MAS:array [1..10] of real); 
так як в списку формальних параметрів фактично оголошується тип-діапазон, що вказує на границі індексів масиву. Якщо ми хочемо передати в підпрограму весь масив, необхідно спочатку описати його тип. Наприклад, в нашому випадку (елементи масиву - цілі числа, тому що вони являється кількістю квітів):
const 
L = 100; 
Type 
T_Mas = array[1..L] of integer; 
Після чого можна описати формальний параметр-масив, як
Procedure S(MAS:T_Mas); 
Даний метод передавання масиву у підпрограму дуже зручний, але зверніть увагу на те, що опис створеного типу повинен мати розмірність найбільшу з усіх призначених для передавання масивів. Якщо з якихось причин неможливо заздалегідь визначити максимальну розмірність масиву, існує інший метод передавання його в підпрограму у якості параметру (Увага! Цей метод діє тільки для одновимірних масивів).
В цьому випадку масив можна описати, як динамічний (тобто з невизначеною заздалегідь довжиною), наступним чином:
Procedure S(MAS:array of integer); 
В цьому описі визначається тільки, що MAS - це одновимірний масив цілих чисел, але кількість елементів з опису не відома. При звертанні до підпрограми фактичний параметр буде визначати довжину масиву, що оброблюється, але будьте уважні: перший елемент формального масиву буде мати індекс 0, а останній, відповідно, на одиницю менший, ніж розмірність масиву, що передається в підпрограму.
Спробуємо з учбовою метою при розв'язанні цієї задачі використати обидва методи передавання масивів в підпрограму.
Необхідні для роботи програми змінні:
A, В, С - масиви, що містить кількість квітів від кожного гнома, звірятка або пташки відповідно;
k, m, l - кількість гномів, звірят та пташок відповідно;
number - номер максимального елементу в масиві ( за умовою задачі необхідно визначити не конкретного персонажа серед гномів, звірят або пташок, а безпосередньо сам "різновид" гостя);
S - масив, що містить суму елементів відповідного масиву A, B або С;
Max - масив, що містить значення максимального елементу з кожного з масивів (А, В, або С).
З урахуванням всього вище сказаного, програма, що розв'язує запропоновану задачу, має наступний вигляд:
Program Example_423; 
Uses crt; {Підключення бібліотеки} 
{Опис типу для масиву} 
const 
L = 100; 
Type 
T_Mas = array[1..L] of integer; 
{Процедура заповнення масиву генератором випадкових чисел з контрольним виведенням на екран вмісту заповненого масиву} 
Procedure Input (var MAS:T_Mas; count:integer); 
var i:integer; 
begin 
for i:=1 to count do 
begin 
MAS[i]:=round(100); {Заповнення масиву  
генератором випадкових чисел} 
write(MAS[i]:6); 
end; 
writeln; 
end; 
{Процедура знаходження суми елементів та максимуму в заданому масиві; count - кількість елементів в масиві, що необхідно обробити} 
Procedure Solution (MAS:T_Mas; count:integer; 
var SUM,MAX :longint ); 
Var i:integer; 
Begin 
SUM:=0; {Початкові значення } 
MAX:=MAS[1]; 
For i:=1 to count do 
begin 
SUM:=SUM+MAS[i]; 
if MAX<MAS[i] 
then MAX:=MAS[i]; 
end; 
End; 
{Процедура пошуку максимуму в масиві} 
Procedure Search_Max(M:array of longint; 
var n_max:integer); 
var i,Maximum:integer; 
begin 
Maximum:=M[0]; n_max:=0; 
for i:=0 to 2 do 
if Maximum<M[i] 
then 
begin 
Maximum:=M[i]; 
n_max:=i; 
end; 
n_max:=n_max+1; 
end; 
Var A,B,C:T_Mas; 
n,m,k,number:integer; 
S,Max:array[1..3] of longint; 
Begin 
Clrscr; 
Writeln('Введіть кількість гостей на дні народження'); 
Write('Кількість гномів: '); 
readln(n) 
Input(A,n); 
Write('Кількість звірят: '); 
readln(M) 
Input(B,m); 
Write('Кількість пташок: '); 
readln(k) 
Input(C,k); 
Solution(A,n,S[1],M[1]); 
Solution(B,m,S[2],M[2]); 
Solution(C,k,S[3],M[3]); 
{Вибір, хто (гноми, звірята чи пташки) принесли  
найбільшу кількість квітів} 
Search_Max(S,number); 
Case number of 
1: Write('Гноми'); 
2: Write('Звірята'); 
3: Write('Пташки'); 
End; 
write(' принесли найбільше квітів.'); 
writeln; 
write('Самий щедрий гість перебуває у '); 
{Вибір, де (у гномів, звірят чи пташок)  
перебуває найщедріший гість} 
Search_Max(M,number); 
Case number of 
1: Write(' гномів.'); 
2: Write(' звірят.'); 
3: Write(' пташок.'); 
End; 
Readkey; 
End. 
 

Задача № 427.
Умова: Організувати зміну кольору екрана для покрокового введення текстової інформації - прізвище, ім'я, школа, клас - за допомогою власної підпрограми COLOR_PAGE. Для вибору номера кольору скористатися генератором випадкових чисел.
Виконаємо цю підпрограму також у вигляді процедури. Спочатку визначимось з формальними параметрами, що будуть передаватися у підпрограму. По-перше, виберемо S - рядкову змінну, що буде містити текст, який виводитиметься на екран перед введенням. По-друге, візьмемо R - змінну рядкового типу для збереження результату введення. Очевидно, що перший з цих параметрів повинен бути параметром-значенням, а другий - параметром-змінною.
Так як програма являється учбовою і не пропонує обробки введених даних, можна використовувати у якості фактичного параметру одну ту саму змінну, наприклад А.
Програма, що виконує запропонований алгоритм, має наступний вигляд:

Program Example_427; 
Uses crt; {Підключення бібліотеки} 
Procedure Solution (S:string; var R:string); 
Begin 
textbackground(Random(14)+1); 
clrscr; 
textcolor(Random(14)+1); 
gotoxy(20,10); 
writeln('Введіть ',S); 
gotoxy(20,11); 
readln(R); 
End; 
Var A:string; 
Begin 
Solution('своє прізвище',A); 
Solution('своє ім"я',A); 
Solution('школу, де Ви навчаєтесь',A); 
Solution('свій клас',A); 
Readkey; 
End. 

Задача № 463.
Умова: Створити підпрограму, яка б із тексту S вилучала вказаний символ х і обчислювала кількість вилучень. У програмі організувати виклик цієї підпрограми.
Очевидно, що підпрограма, яка виконує дану задачу, повинна мати три формальних параметри. Позначимо їх наступним чином:
S - заданий текст (змінна рядкового типу string);
x - символ, що підлягає вилученню (змінна символьного типу char);
count - кількість вилучень (числова змінна цілого типу, наприклад byte).
Параметр x повинен бути параметром-значенням (вхідний параметр), а параметри S та count параметрами-змінними (вихідні параметри). Рядок S фактично являється і вхідним, і вихідним, тому що за умовою задачі саме в ньому необхідно здійснити вилучення заданих символів.
Для виконання поставленої задачі, на наш погляд, зручніше використовувати цикл з передумовою, тому що після вилучення символів з рядку він змінює свою довжину і використання циклу з параметром (for) може привести до помилки. Крім того, зверніть увагу на те, що зміна індексу і (номер поточної позиції рядка) виконується тільки у випадку, якщо шуканий символ не знайдено. Це пов'язано з тим, що рядок може містити цей символ у сусідніх позиціях і після вилучення поточного символу на ту саму позицію попадає знов шуканий символ.
Оформлення основної програми, на наш погляд, не повинно викликати сумнівів. Зазначимо лише, що відповідні фактичні параметри у запропонованій програмі будуть називатися А (заданий текст), ch (символ, що підлягає вилученню), N (кількість вилучень).
Програма, що виконує запропонований алгоритм, має наступний вигляд:

Program Example_463; 
Uses crt; {Підключення бібліотеки} 
Procedure Solution (x:char; var S:string;  
var count:byte); 
var i:byte; {локальна змінна для організації  
циклу} 
Begin 
count:=0; i:=1; 
while i<=length(S) do 
begin 
if S[i]=x  
then 
begin 
count:=count+1; 
delete(S,i,1); 
end 
else i:=i+1; 
end; 
End; 
Var A:string; ch:char; N:byte; 
Begin 
clrscr; 
writeln  ('Введіть текст: '); 
readln(A); 
write ('Введіть шуканий символ: '); 
readln (ch); 
Solution(^ch,A,N); 
writeln ('Результуючий текст: ',A); 
writeln ('Кількість виконаних вилучень: ',N); 
readkey; 
End.