МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
С.І. БОБАЛО
О.Е. МАРКЕЛОВ
ЛАБОРАТОРНИЙ ПРАКТИКУМ
з курсу “Основи програмування”
Частина 2
Рекомендовано до друку Науково-методичною радою
Національного університету “Львівська політехніка”
як навчальний посібник для студентів напрямів підготовки
6.0305 “Філологія” та 6.0804 “Комп’ютерні науки”
Львів
Видавництво Національного університету “Львівська політехніка”
2005
ББК 32.973.01 я73
Б 72
УДК 004.432(075.8)
Рекомендовано до друку Науково-методичною радою
Національного університету “Львівська політехніка”
як навчальний посібник для студентів напрямів підготовки
“Філологія” та “Комп’ютерні науки”
(протокол № 12 від 13.10.2004 р.)
Рецензенти:
Федасюк Д.В., доктор технічних наук, професор Національного університету “Львівська політехніка”;
Русин Б.П., доктор технічних наук, професор, завідувач відділу Фізико-механічного інституту ім. Г.В. Карпенка НАН України;
Дунець І.Б., кандидат технічних наук, доцент кафедри автоматизації та комп’ютерних технологій Української академії друкарства.
Бобало С.І., Маркелов О.Е.
Лабораторний практикум з курсу “Основи програмування”. Ч. 2: Навч. посібник. – Львів: Видавництво Національного університету “Львівська політехніка”, 2005. – 184 с.
ISBN 966-553-463-7
У посібнику подано сім інструкцій до виконання лабораторних робіт з курсу “Основи програмування”.
Для студентів базових напрямів 6.0305 “Філологія” та 6.0804 “Комп’ютерні науки”.
ББК 32.973.01 я73
© Бобало С.І.,
Маркелов О.Е., 2005
© Національний університет
“Львівська політехніка”, 2005
ВСТУП
Навчальний посібник “Лабораторний практикум з основ програмування” (частина 2) є логічним продовженням роботи авторів над курсом “Основи програмування” для студентів напрямів підготовки 6.0305 “Філологія” та 6.0804 “Комп’ютерні науки”.
Мета цієї частини посібника – ознайомити студентів зі складними структурами та прийомами роботи з алгоритмічною мовою програмування Паскаль та показати, як можна за їхньою допомогою складати прикладні програми обробки складних даних, текстів та математичних розрахунків.
Весь матеріал поділено на окремі теми (лабораторні роботи), які містять теоретичну частину, контрольні запитання, зміст оформлення звіту по роботі, загальне лабораторне завдання, окремі індивідуальні завдання, виконавши які студент засвоїть певну тему. У теоретичній частині розкрито основні аспекти мови Паскаль на конкретну тему, наведено багато прикладів, які ілюструються блок-схемами алгоритмів та схематичними рисунками.
У посібнику наведено основні відомості про підпрограми – процедури та функції, які зручно використовувати для підвищення структурованості об’ємних програм та розбиття складних програм на завершені частини з можливістю незалежного програмування кількома програмістами. Теоретичні відомості дають змогу вивчити особливості застосування різних видів параметрів процедур та функцій, глобальних та локальних змінних, рекурсивних функції та правил їх застосування, можливих побічних ефектів у разі використання процедур та функцій.
Ознайомлення у цьому навчальному посібнику із множинним типом у мові Паскаль дозволить закріпити знання, набуті з курсу “Дискретна математика”, дасть змогу показати та практично випробувати вміння працювати з множинним типом та математичними і логічними операціями над множинами, дозволить набути навичок програмування з використанням множин.
Вивчення особливостей застосування комбінованих типів у разі роботи зі складними структурами даних дає можливість задати образ об’єктів, кожна частина якого може мати різні характеристики. Розуміння та використання ієрархічних записів та записів із варіантною (змінною) частинами сприяє деталізації та послідовній структуризації змінних, що описують складну інформаційну будову даних. Набуті знання будуть сприяти кращому засвоєнню матеріалу з курсу “Основи організації баз даних”.
Вивчення динамічних структур організації даних (однонаправлені та двонаправлені списки, стеки, черги) дасть змогу створювати програми для розв’язання задач, залежних від розмірності, обсягу даних, що повинні зберігатися в оперативній пам’яті, та постійної їхньої кількісної зміни під час роботи програми. Застосування динамічних структур даних повинно сприяти раціональному виділенню ємності оперативної пам’яті під зберігання даних та швидшому доступу, пошуку, вставці та видалення інформації великих обсягів.
Практичні навички отримані під час ознайомлення з представленням даних у вигляді бінарного дерева дає можливість однаково ефективно реалізовувати операції: пошуку, включення та видалення запису з динамічної структури даних. Оскільки дані постійно отримують впорядкування на основі власної організації зв’язків і не потребують постійного примусового узагальненого впорядкування.
У посібнику, на відміну від математичних, фізичних чи хімічних, не наводяться відповіді на завдання, оскільки відповіддю є сам алгоритм чи програма, розроблені на лабораторних заняттях. Відповідь на запитання, чи правильно складений алгоритм, дасть сам комп’ютер у разі відлагодження та тестування програми у інтегрованому середовищі програмування мовою Паскаль, наприклад, Turbo Pascal 7.1
Лабораторна робота № 8
ПРОЦЕДУРИ В АЛГОРИТМІЧНІЙ МОВІ ПАСКАЛЬ
1. МЕТА РОБОТИ
Мета роботи – ознайомитися з особливостями застосування підпрограм в алгоритмічній мові Паскаль. Вивчити особливості застосування різних видів параметрів процедур, глобальних та локальних змінних. Набути практичних навичок програмування з використанням процедур.
2. ТЕОРЕТИЧНІ ВІДОМОСТІ
2.1. ПІДПРОГРАМИ
Дуже часто виникає потреба, коли одна й та сама послідовність дій повинна виконуватись на різних етапах обробки інформації. В алгоритмах такого роду в різних місцях зустрічаються фрагменти, які однакові за діями, що виконуються, але відрізняються лише значеннями початкових даних.
Для ефективнішого програмування введено поняття підпрограма. Група операторів, які будуть повторюватись, оформляється у вигляді самостійної програмної одиниці – підпрограми, записуються один раз, а у відповідних місцях основної програми забезпечується лише звертання до неї.
Використання апарата підпрограм дає змогу скоротити об’єм і покращити структуру програми з точки зору наочності та зручності читання, зменшити ймовірність помилок і полегшити відлагодження програми. Розділення програми на взаємозв’язані, але замкнуті та логічно завершені компоненти дає можливість розроблювати окремі підпрограми різними програмістами та більш-менш незалежно один від одного. Крім того, підпрограму можна розглядати як самостійний модуль (зі своїми вхідними та вихідними даними), що дає змогу використовувати її в загальному ієрархічному підході під час конструювання алгоритму та програми за принципами низхідного проектування.
Мовою Паскаль підпрограми реалізуються у вигляді процедур і функцій, які вводяться в основну програму за допомогою свого опису.
2.2. ОПИС ПРОЦЕДУР У МОВІ ПАСКАЛЬ
Процедура описується у спеціальному розділі описової частини основної програми після опису змінних. Структура процедури аналогічна структурі основної програми. Процедура складається із заголовка і тіла процедури. Тіло процедури, у свою чергу, містить розділ описів і розділ операторів.
PROCEDURE <ім’я> (<формальні параметри>:<тип формальних параметрів>);
<Розділ описів і визначень локальних параметрів процедури>
BEGIN
<оператор 1>;
<оператор 2>;
........
<оператор n>
END;
Синтаксична діаграма опису процедури відповідно має вигляд, наведений на рис. 1.
Рис. 1. Синтаксична діаграма опису процедури
Список параметрів, синтаксична діаграма якого наведена на рис. 2, являє собою перелік імен для позначення вхідних даних і результатів роботи процедури з вказанням їхнього типу. Параметри, які перераховуються в заголовку процедури, називаються формальними. Ці параметри використовуються тільки в тілі процедури.
Рис. 2. Синтаксична діаграма опису списку параметрів
Допускається опис процедур, які зовсім не містять параметрів.
2.3. ВИКЛИК ПРОЦЕДУР
Виклик процедури здійснюється у потрібному місці основної програми за допомогою оператора виклику процедури.
<ідентифікатор>(<список фактичних параметрів>);
де <ідентифікатор> – це ім’я процедури.
У разі виклику процедури формальні параметри, які вказані в її заголовку, замінюються аргументами (фактичними параметрами) у тій послідовності, у якій вони розміщені в операторі виклику процедури. Кількість і тип формальних та фактичних параметрів повинні збігатися.
Наприклад: заголовок опису процедури:
PROCEDURE SUM1 (A,B:REAL;VAR S:REAL);
Виклик процедури SUM1 здійснюється оператором:
SUM1 (A1,B1,S1);
Якщо процедура без параметрів, то виклик проводиться тільки за її ім’ям.
Наприклад:
Заголовок процедури:
PROCEDURE SUM;
Виклик такої процедури здійснюється оператором:
SUM;
2.4. ПАРАМЕТРИ ПРОЦЕДУРИ
У разі опису процедури в її заголовку можуть бути вказані параметри чотирьох видів:
параметри-значення;
параметри-змінні;
параметри-функції;
параметри-процедури.
Параметри-значення використовуються для передачі вхідних даних у підпрограму. У списку формальних параметрів вони перераховуються через кому з обов’язковим вказуванням їхнього типу, наприклад:
PROCEDURE FS1(A,B: REAL; I,Y: INTEGER);
Як відповідний фактичний параметр у разі виклику процедури може використовуватись або довільний вираз відповідного типу, або змінна, або константа.
FS1(A1+S/3,B1,9,24);
Якщо фактичний параметр заданий виразом, то цей вираз спочатку обчислюється і вже конкретне значення підставляється замість нього.
Під час виконання процедури формальні параметри можуть змінюватися, але це ніяк не позначається на відповідних фактичних параметрах-значеннях, оскільки вони зберігають своє початкове значення. Тому параметри-значення не можна використовувати для повернення результату в головну програму.
Параметри-змінні використовуються для повернення результатів виконання процедури в головну програму.
У списку формальних параметрів вони перераховуються після службового слова VAR із обов’язковим вказуванням типу:
PROCEDURE MINMAX (A, B, C: REAL; VAR MIN,MAX: REAL);
Фактичні параметри, що відповідають параметрам-змінним, повинні бути тільки змінними цього самого типу, тобто:
MINMAX (A1, B1, C1, SMIN, SMAX);
При виклику процедури і заміні формальних параметрів-змінних на фактичні параметри здійснюється передача адреси змінної, а не її значення. Отже, у комірки з іменем SMIN та SMAX буде записано результати MIN та MAX, обчислені в процедурі MINMAX.
Як формальні параметри в мові Паскаль допускається використання імені процедур і функцій, описаних раніше.
Параметри-процедури в списку формальних параметрів описуються після службового слова PROCEDURE.
Наприклад:
PROCEDURE PRS (A,B: REAL;VAR Z: REAL; PROCEDURE SUM);
При виклику підпрограми на місце формальних параметрів процедур підставляються фактичні процедури. Якщо ці процедури мають у свою чергу параметри, то ці параметри можуть бути тільки параметрами-значеннями. У багатьох задачах, особоливо задачах обчислювальної математики, необхідно передавати імена процедур і функцій як параметри. Для цього в Turbo Pascal введений тип даних – процедурний чи функціональний тип, залежно від того, що описується. Опис процедурного чи функціонального типів проводиться у розділі опису типів:
TYPE FUN1 = FUNCTION (Z:REAL): REAL;
PRO3 = PROCEDURE (A,B:REAL; VAR X,Y: REAL);
Функціональний та процедурний типи визначаються як заголовок процедури чи функцій зі списком формальних параметрів, але без імені. Можна описувати цей тип і без параметрів.
Після опису процедурного чи функціонального типу його можна використовувати для опису формальних параметрів – імен процедур та функцій. Крім того, необхідно написати тіла тих реальних процедур та функцій, імена яких будуть передаватися як фактичні параметри.
2.5. ГЛОБАЛЬНІ ТА ЛОКАЛЬНІ ЗМІННІ
Усі змінні, описані в розділі опису змінних до опису процедур, є глобальними змінними. Вони зберігають своє значення протягом виконання всіх функцій і процедур, а також головної програми.
Змінні, описані в розділі опису змінних конкретної процедури або функції, є локальними змінними. Їхні значення зберігаються лише на час виконання функції або процедури та діють лише у цих функціях та процедурах, а також у будь-якій описаній в них процедурі чи функції (вкладені процедури чи функції). Локальні змінні недоступні для операторів головної програми.
PROGRAM TESTPROC (INPUT, OUTPUT);
VAR A0,B0,C0 : INTEGER; {Опис глобальних змінних}
{Ця процедура є підпрограмою головної програми}
PROCEDURE P1;
VAR A1,B1,C1:INTEGER; {Опис локальних змінних для процедури Р1 та відповідно вони є глобальними для Р2}
PROCEDURE P2; {Ця процедура є підпрограмою процедури Р1}
VAR A2,B2,C2:INTEGER; {Опис локальних змінних для процедури Р2}
BEGIN
{Допустиме використання глобальних A0, B0, C0, A1, B1, C1
так і локальних A2, B2, C2}
END;
BEGIN
{Допустиме використання глобальних A0, B0, C0 так і локальних A1, B1, C1}
END;
{Ця процедура є підпрограмою головної програми}
PROCEDURE P3(N1,N2:INTEGER;S1,S2:CHAR;VAR K1:REAL;G1:STRING);
VAR A3,B3,C3:INTEGER; {Опис локальних змінних для процедури Р3 та відповідно вони є глобальними для Р4}
PROCEDURE P4; {Ця процедура є підпрограмою процедури Р3}
VAR A4,B4,C4:INTEGER; {Опис локальних змінних для процедури Р4}
BEGIN
{Допустиме використання глобальних A0, B0, C0, A3, B3,C3, N1,N2, S1,
S2, K1, G1 так і локальних A4, B4, C4 }
END;
BEGIN
{Допустиме використання глобальних A0, B0, C0 локальних A3, B3, C3 так і значень формальних параметрів N1,N2, S1,S2 як вхідні параметри, та K1, G1 як вихідні параметри}
END;
BEGIN {Початок головної програми}
{Допустиме використання лише глобальних змінних A0, B0, C0}
END.
Рис. 3. Принцип локалізації змінних у разі застосування процедур у мові Паскаль
Продемонструємо відмінність між локальними та глобальними змінними на прикладі простої програми.
Приклад:
Залежно від значення дійсних змінних X та Y обчислити:
U=max (X+Y, X-Y)
V=max (2,7, U)
Без використання процедури програма буде мати такий вигляд:
PROGRAM TEST1 (INPUT, OUTPUT);
VAR X,Y,U,V: REAL;
BEGIN
READLN (X,Y);
IF (X+Y)>(X-Y) THEN U:=X+Y
ELSE U:=X-Y;
IF 2.7>U THEN V:=2.7
ELSE V:=U;
WRITELN (’U=’, U, ’V=’,V)
END.
Один і той самий умовний оператор виконується двічі з різними параметрами. Замінимо його процедурою MAX1 без параметрів:
PROGRAM TEST2 (INPUT, OUTPUT)
VAR X,Y,U,V: REAL; {глобальні змінні}
A, B, S: REAL; {глобальні змінні}
PROCEDURE MAX1;
BEGIN {початок процедури}
IF A>B THEN S:=A
ELSE S:=B
END; {закінчення процедури}
BEGIN {початок основної програми}
READLN (X,Y);
A:=X+Y;
B:=X-Y;
MAX1; {перший виклик процедури без параметрів}
U:=S;
A:=2.7;
B:=U;
MAX1;{другий виклик процедури без параметрів}
V:=S;
WRITELN (’U=’, U, ’V=’,V)
END.
Змінні А та В є глобальними змінними програми TEST2. Перед викликом процедури MAX1 їм необхідно присвоїти відповідні значення: у першому випадку A:=X+Y; B:=X+Y; у другому випадку A:=2.7, B:=U.
Результат виконання процедури передається в головну програму через глобальну змінну S.
Доцільніше передавати значення змінних А та В у підпрограму за допомогою фактичних і формальних параметрів.
PROGRAM TEST3 (INPUT, OUTPUT);
VAR X,Y,U,V:REAL; {глобальні змінні}
S:REAL; {глобальні змінні}
PROCEDURE MAX2 (A,B:REAL); {є формальні параметри А та В}
BEGIN {початок процедури}
IF A>B THEN S:=A
ELSE S:=B;
END; {закінчення процедури}
BEGIN {початок основної програми}
READLN (X,Y);
MAX2(X+Y, X-Y);{перший виклик процедури з фактичними параметрами}
U:=S;
MAX2(2.7,U); {другий виклик процедури з фактичними параметрами}
V:=S;
WRITELN (’U=’,U,’V=’,V)
END.
У разі виклику процедури МАХ2, значення X+Y та X-Y через формальні параметри А та В передаються у процедуру. Це параметри-значення і вони визначають початкові дані для роботи процедури MAX2 при конкретному її виклику. Фактичні параметри X+Y та X-Y у цьому випадку є виразом, який за типом збігається з типом формальних параметрів А та В.
При виході з процедури параметри-значення стають недоступні, тому для повернення результату в головну програму використано глобальну змінну S. Але для цієї мети краще використати параметр-змінну, через яку буде повертатись результат.
PROGRAM TEST4 (INPUT, OUTPUT);
VAR X,Y,U,V:REAL; {глобальні змінні}
PROCEDURE MAX3 (A,B:REAL; VAR S:REAL); {є формальні параметри та змінні}
BEGIN {початок процедури}
IF A>B THEN S:=A
ELSE S:=B;
END; {закінчення процедури}
BEGIN {початок основної програми}
READLN (X,Y);
MAX3(X+Y, X-Y, U); );{перший виклик процедури з фактичними параметрами та змінними}
MAX3(2.7, U, V); {другий виклик процедури з фактичними параметрами та змінними}
WRITELN (’U=’,U, ’V=’, V)
END.
Формальний параметр-змінна S записується після службового слова VAR, передає вихідний результат із процедури в головну програму. Ця передача здійснюється через вказівник на цю змінну, а не через її значення.
2.6. ОСОБЛИВОСТІ ВИКОРИСТАННЯ ЗМІННИХ РІЗНИХ ТИПІВ ЯК ФОРМАЛЬНИХ ПАРАМЕТРІВ
Формальними параметрами процедури можуть бути змінні будь-якого типу: масиви, множини, файли, записи, змінні перелічуваного або обмеженого типів. Але слід пам’ятати, що тип формальних параметрів необхідно визначити тільки ідентифікатором.
Не допускається запис такого вигляду:
PROCEDURE SMAS (A:ARRAY[1..20] OF INTEGER, VAR S:REAL) {помилка}
Тому що опис ARRAY[1..20] OF INTEGER не є простим ідентифікатором.
Замість нього потрібно в розділі опису типу головної програми описати відповідний тип із назвою-ідентифікатором у розділі опису типів:
TYPE
MAS=ARRAY [1..20] OF INTEGER; {описаний ідентифікатор MAS}
а тоді в описі процедури використати цей простий ідентифікатор типу:
PROCEDURE SMAS (A:MAS;VAR S:REAL);
Таке обмеження накладене умовою еквівалентності типів у мові Паскаль.
Явне задання типу формального параметра виключає можливість зіставлення його з типом фактичного параметра.
Приклад: обчислити суму елементів масиву А, що містить 20 елементів, і масиву В, що містить 30 елементів.
Так, якщо нам потрібно обчислити суму елементів масиву А(20) та масиву В(30), то потрібно описувати дві процедури: одна – буде обчислювати суму елементів масиву А, а інша – масиву В.
PROGRAM TESTM1 (INPUT, OUTPUT);
TYPE
MAS20=ARRAY [1..20] OF INTEGER; {опис ідентифікаторів типу}
MAS30=ARRAY [1..30] OF INTEGER;
VAR {глобальні змінні}
A:MAS20;
B:MAS30;
SA, SB: INTEGER;
{процедура для вводу масиву A}
PROCEDURE VVODA (X:MAS20);
VAR I: INTEGER; {локальна змінна}
BEGIN
FOR I:=1 TO 20 DO
READ(X[I])
END;
{процедура для вводу масиву B}
PROCEDURE VVODB (X:MAS30);
VAR I: INTEGER; {локальна змінна}
BEGIN
FOR I:=1 TO 30 DO
READ(X[I])
END;
{процедура для обчислення суми масиву A}
PROCEDURE SUMA (X:MAS20; VAR S: INTEGER);
VAR I: INTEGER; {локальна змінна}
BEGIN
S:=0;
FOR I:=1 TO 20 DO
S:=S+X[I]
END;
{процедура для обчислення суми масиву В}
PROCEDURE SUMB (X:MAS30; VAR S: INTEGER);
VAR I: INTEGER; {локальна змінна}
BEGIN
S:=0;
FOR I:=1 TO 30 DO
S:=S+X[I]
END;
{основна програма}
BEGIN
VVODA (A); {виклик процедури}
VVODB (B); {виклик процедури}
SUM (A, SA); {виклик процедури}
SUM (B, SB); {виклик процедури}
WRITELN (’A=’, SA, ’B=’, SB)
END.
Особливого виграшу в компактності програми у разі використання процедур у цьому випадку не маємо. Це є недоліком для мови Паскаль: не можна ввести процедуру для обробки масивів різних типів навіть тоді, коли вони відрізняються тільки кількістю компонентів.
Але виходом із цієї ситуації буде те, що ми можемо описати масиви однакової, найбільшої довжини, а заповнювати й обробляти їх відповідно до їхньої розмірності.
Блок-схеми основної програми, алгоритму введення масиву, алгоритму обчислення суми елементів масиву наведено на рис. 4, 5, 6, відповідно.
Рис. 4. Блок-схема
основної програми
Рис. 5. Блок-схема
алгоритму вводу масиву
VVOD
Рис. 6. Блок-схема алгоритму обчислення суми SUM
Текст програми:
PROGRAM TEST2 (INPUT, OUTPUT);
TYPE
MAS=ARRAY[1..30] OF INTEGER;
VAR {глобальні змінні}
A, B: MAS;
SA, SB: INTEGER;
{процедура для вводу вказаного масиву}
PROCEDURE VVOD (X:MAS; K: INTEGER);
VAR I: INTEGER; {локальна змінна}
BEGIN
FOR I:=1 TO K DO
READ ( X[I] )
END;
{процедура для обчислення суми вхідного масиву}
PROCEDURE SUM (X:MAS; K: INTEGER; VAR S :INTEGER);
VAR I: INTEGER; {локальна змінна}
BEGIN
S:=0;
FOR I:=1 TO K DO
S:=S+X[I]
END;
BEGIN {основна програма}
VVOD (A, 20); {виклик процедури з новими параметрами}
VVOD (B, 30); {виклик процедури з новими параметрами}
SUM (A, 20, SA); {виклик процедури з новими параметрами}
SUM (B, 30, SB); {виклик процедури з новими параметрами}
WRITELN (’SUMA=’, SA, ’SUMB=’, SB)
END.
2.7. ПРИКЛАДИ ВИКОРИСТАННЯ ПРОЦЕДУР
Приклад: фрагмент тексту містить 8 рядків. Обчислити скільки разів у кожному рядку зустрічається слово “BIG”. Вивести на екран рядок, у якому цих слів найбільше. Урахувати появи слова на початку рядка, коли “BIG”; усередині рядка, коли “BIG”; та наприкінці рядка, коли “BIG”.
Розв’язання: складемо алгоритм спочатку без використання підпрограми. Блок-схему алгоритму наведено на рис. 7.
Блок 1 – початок алгоритму.
Блоки 2, 3 – ввід у циклі пострічково фрагмента тексту.
Блоки 4–15 – визначення кількості слів “BIG” у кожному рядку тексту, зокрема:
Блок 5 – обнулення лічильника К кількості слів.
Блок 6 – визначення першого та останнього слова як фрагмента рядка у вигляді буквосполучень із чотирьох літер для отримання “BIG” та “BIG” на початку рядка та наприкінці рядка, відповідно.
Блоки 7, 8 – перевірка: чи перший фрагмент рядка є словом “BIG”; якщо – так, то лічильник К збільшується на одиницю.
Блоки 9, 10 – перевірка: чи останній фрагмент рядка є словом “BIG”; якщо – так, то лічильник К збільшується на одиницю.
Блоки 11–14 – циклічна перевірка: чи поточний фрагмент рядка є словом “BIG”; якщо – так, то лічильник К збільшується на одиницю.
Блок 12 – визначення поточного фрагмента рядка у вигляді буквосполучення з п’яти літер для отримання “BIG”.
Блок 15 – кількість слів К записується в масив KS[i] для кожного рядка тексту.
Блоки 16, 17 – циклічний вивід елементів масиву KS.
Блок 18 – уважаємо, що спочатку найбільша кількість слів “BIG” є в першому рядку.
Блоки 19–22 – пошук у циклі максимальної кількості KS та його номер NMAX.
Блок 23 – вивід результату максимальної кількості MAX та номера рядка NMAX.
Блок 24 – кінець алгоритму.
Текст програми без застосування процедури (де – символ пробілу):
PROGRAM TBP (INPUT,OUTPUT);
TYPE
TST=STRING[80];
VAR
MSTR:ARRAY[1..8] OF TST;
KS:ARRAY[1..8] OF INTEGER;
I,J,K,MAX,NMAX:INTEGER;
S1,S2:STRING[4];
S3:STRING[5];
BEGIN
WRITELN(’ВВЕДIТЬ ТЕКСТ’);
FOR I:=1 TO 8 DO
READLN(MSTR[I]);
FOR I:=1 TO 8 DO
BEGIN
K:=0;
S1:=COPY(MSTR[I],1,4);
S2:=COPY(MSTR[I],LENGTH(MSTR[I])-3,4);
IF S1=’BIG’ THEN K:=K+1;
IF S2=’BIG’ THEN K:=K+1;
FOR J:=1 TO LENGTH(MSTR[I])-4 DO
BEGIN
S3:=COPY(MSTR[I],J,5);
IF S3=’BIG’ THEN K:=K+1;
END;
KS[I]:=K
END;
WRITELN(’РЕЗУЛЬТАТ KS:’);
FOR I:=1 TO 8 DO
WRITELN(’У’, I, ’РЯДКУ Є’,KS[I],’СЛIВ’);
MAX:=KS[1];
NMAX:=1;
FOR I:=2 TO 8 DO
IF KS[I]>MAX THEN
BEGIN
MAX:=KS[I];
NMAX:=I
END;
WRITELN(’НАЙБIЛЬШЕ СЛIВ BIG У’, NMAX, ’РЯДКУ’);
WRITELN(MSTR[NMAX])
END.
Частину алгоритму, а саме знаходження кількості слів “BIG” у одному рядку (блоки 5–14) можна виокремити у підпрограму (процедуру чи функцію).
Алгоритм буде ілюструватися вже не однією, а двома блок-схемами: блок-схемою основної програми та блок-схемою процедури або функції. Виклик підпрограми (процедури чи функції) у алгоритмі головної програми на блок-схемах позначається таким умовним позначенням (блоком):
Блок-схеми з використанням підпрограм наведено на рис. 8, 9. Блок-схему алгоритму основної програми зображено на рис. 8.
Блок 1 – початок алгоритму.
Блоки 2, 3 – ввід у циклі пострічково фрагмента тексту.
Блоки 4, 5 – циклічний виклик підпрограми KBIG з передаванням вхідного рядка на обробку та присвоювання результату поточному значенню масиву KS[i], де I змінюється від 1 до 8.
Блок 6, 7 – циклічний вивід елементів масиву KS (кількість слів BIG у кожному рядку).
Рис. 8. Блок-схема алгоритму Рис. 9. Блок-схема алгоритму основної програми підпрограми KBIG
Блок 8 – уважаємо, що спочатку найбільша кількість слів “BIG” є в першому рядку.
Блоки 9, 10, 11, 12 – пошук у циклі максимальної кількості масиву KS та його номер NMAX.
Блок 13 – вивід результату максимальної кількості MAX та номера рядка NMAX.
Блок 14 – кінець основної програми.
Блок-схему підпрограми KBIG наведено на рис. 9.
Блок 1 – початок алгоритму.
Блоки 2–11 – визначення кількості слів “BIG” у рядку тексту, зокрема:
Блок 2 – обнулення лічильника К1 кількості слів.
Блок 3 – визначення першого S1 та останнього S2 слова як фрагмента рядка у вигляді буквосполучень із чотирьох літер для отримання “BIG” та “BIG” на початку рядка та наприкінці рядка відповідно.
Блок 4 – перевірка: чи перший фрагмент рядка є словом “BIG”; якщо – так, то:
Блок 5 – лічильник К1 збільшується на одиницю.
Блок 6 – перевірка: чи останній фрагмент рядка є словом “BIG”; якщо – так, то:
Блок 7 – лічильник К1 збільшується на одиницю.
Блоки 8–11 – циклічна перевірка: чи поточний фрагмент рядка є словом “BIG”; якщо – так, то лічильник К1 збільшується на одиницю, зокрема:
Блок 9 – визначення поточного фрагмента рядка у вигляді буквосполучення з п’яти літер для отримання “BIG”.
Блок 10 – перевірка: чи перший фрагмент рядка є словом “BIG”; якщо – так, то:
Блок 11 – лічильник К1 збільшується на одиницю.
Блок 12 – кінець підпрограми.
Текст програми з використанням підпрограми (де – символ пробілу):
PROGRAM TBP2 (INPUT,OUTPUT);
TYPE
TST=STRING[80];
VAR
MSTR:ARRAY[1..8] OF TST;
KS:ARRAY[1..8] OF INTEGER;
I,MAX,NMAX:INTEGER;
{ПIДПРОГРАМА}
PROCEDURE KBIG (STR:TST; VAR K1:INTEGER);
VAR
J:INTEGER;
S1,S2:STRING[4];
S3:STRING[5];
BEGIN
K1:=0;
S1:=COPY(STR,1,4);
S2:=COPY(STR,LENGTH(STR)-3,4);
IF S1=’BIG’ THEN K1:=K1+1;
IF S2=’BIG’ THEN K1:=K1+1;
FOR J:=1 TO LENGTH(STR)-4 DO
BEGIN
S3:=COPY(STR,J,5);
IF S3=’BIG’ THEN K1:=K1+1;
END;
END;
{ГОЛОВНА ПРОГРАМА}
BEGIN
WRITELN(’ВВЕДIТЬ ТЕКСТ’);
FOR I:=1 TO 8 DO
READLN(MSTR[I]);
FOR I:=1 TO 8 DO