Вивчити можливі варіанти організації циклічних обчислень у програмі за допомогою оператора циклу з параметром.
Основні теоретичні відомості
Загальні відомості
При розробці алгоритмів розв’язання більшості задач виникає необхідність повторення низки кроків. Це призводить до неодноразового використання одних і тих самих операторів у програмі за різних значеннь змінних.
Для організації зручної форми повторних обчислень застосовуються оператори циклу.
У мові Паскаль використовуються три види операторів циклу:
1) оператор циклу з параметром;
2) оператор циклу з попередньою умовою (передумовою);
3) оператор циклу з подальшою умовою (післяумовою);
Оператор циклу з параметром використовується у тих випадках, коли заздалегідь відомо, скільки разів повинна повторюватись циклічна частина програми. Оператор циклу з параметром має дві форми запису:
1) for i:=n to k do <оператор>;
2) for i:=n downto k do <оператор>;
Тут For (для), to (до), downto (зменшує до), do(виконати)-службові слова; i – параметр циклу; n та k – вирази, що задають початкове та кінцеве значення параметра циклу відповідно; <оператор> – простий чи складений оператор. Тип параметра циклу обов’язково має збігатися з типом початкового та кінцевого значення циклу (у якості параметра циклу не можна використовувати змінні типу real).
Оператор циклу починається з перевірки виконання умови i<=k для циклу типу to(i>=k для циклу типу downto). Оператор циклу виконується лише у тому разі, коли ця умова – істина (True).
Потім параметрові циклу присвоюється наступне значення і:= succ(i) (для циклу типу to) або попереднє і:=pred(i) (для циклу типу downto). Далі весь процес повторюється: перевіряється умова i<=k (або i>=k) і якщо ця умова є істина, то знову виконується оператор. Отже, параметр циклу i змінюється з кроком 1 або –1. Неможливо задати крок, котрий не дорівнює 1 або –1.
Розглянемо такий приклад: треба надрукувати всі парні та непарні числа від 1 до 10. Парні числа обчислюються за формулою p=2*k, непарні – m=2*k-1, де k=1,2,...,n. Зрозуміло, що у нашому випадку значення k має змінюватись від 1 до 5. Тоді поставлену задачу зреалізуємо таким фрагментом програми, cхема алгоритму якої приведена на рис.3.1 (у програмі всі змінні цілого типу):
for k:=1 to 5 do
begin
m:=2*k-1;
p:=2*k;
Str(m:4,Sm); Str(p:4,Sp);
ListBox1.Items.Add(‘m=’+Sm+’ p=’+Sp);
end;
При виконанні програми параметр циклу k змінюється від 1 то 5, а змінні p та m набувають таких значеннь:
Рисунок.3.1 – Схема алгоритму
m : 1 3 5 7 9 p : 2 4 6 8 10
Для змінної циклу з параметром існують певні обмеження:
1) значення параметра циклу, початкове та кінцеве значення параметра змінювати усередині циклу не дозволяється;
2) увійти в цикл можна лише через його початок, а вийти – або за умови, що всі значення парамера циклу вичерпано, або при виконанні оператора переходу згідно позначки, розташованою за даним циклом. Можна також вийти з циклу, використовуючи процедуру дострокового виходу з циклу Break.
Отже, оператор циклу з параметром дозволяє здійснити послідовне переберання значень параметра у будь-якому з двох напрямків, але з кроком, який дорівнює одиниці відповідного типу даних. Для завчасного початку чергової ітерації циклу можна використати процедуру Continue.
Розглянемо приклад використання процедур Break і Continue. Нехай потрібно обчислити добуток за формулою:
Звернімо увагу на таке:
· при k=0 значення співмножника перетворюється на нескінченість;
· при k= –2, k= –3 і k= 3 значення співмножників рівні нулю, а отже весь добуток перетворюється в нуль.
· значення добутку при великих "n" швидко збільшуються.
При розв’язанні таких задач необхідно ввести обмеження на величину добутку і передбачити пропуск значень "k" з врахуванням зроблених зауважень. Обмежимо величину "р", а саме, поставимо умову: при р>107 припинити обчислення. Приведемо фрагмент програми обчислення добутку:
p:=1;
for i:=-5 to n do
if p>1e7 then break
else
if (k=0) or (k=-2) or (k=-3) or (k=3) then continue
else p:=p*(k+2)/k*(k*k-9);
Примітка. Цикли можуть бути вкладеними один в одний. Інакше їх називають вкладеними циклами. При використанні вкладених циклів необхідно, складати програму таким чином, щоб внутрішній цикл повністю вкладався у тіло зовнішнього циклу. Внутрішній цикл може також в свою чергу містити інший внутрішній цикл.
Розглянемо приклад складання вкладених циклів та відповідно структурну схему алгоритму обчислення. Припустімо, що необхідно надрукувати значення (2n+1)! при зміні n від 1 до 5.
Нагадаємо, що (n)! називається факторіалом й обчислюється за формулою: (n)!=1*2*3*...*(n–2)*(n–1)*n
Програма та схема алгоритму (рис.2..4.2) можуть мати такий вигляд: (значення факторіалу є ціле число, яке має перебувати в діапазоні значень 1...32767. За великих значень nфакторіал рекомендовано обчислювати, як дійсну величину).
Function fact(n:integer):real;
var m,i:integer;
begin
for i:=1 to n do
begin
fact:=1;
for m:=1 to 2*n+1 do
fact:=fact*m;
end;
Результат обчислення:
За n=1 факторіал = 6
За n=2 факторіал = 120
За n=3 факторіал = 5040
За n=4 факторіал = 362880
За n=5 факторіал =39916800
Рисунок 3.2 –Cхема алгоритму
(Поміркуйте, як можна спростити програму).
2.2 Приклади складання циклічних програм
Приклад 1. Надрукувати літери латинського абетки. При складанні програми треба користуватися тим, що літери абетки упорядковано.
Встановимо на формі дві кнопки Button1, Button2 і компонент StaticText, розташований на вкладці палітри компонентів Additional. Властивості для цих компонентів наведені в таблиці 3.1.
Таблиця 3.1 – Властивості компонентів форми першого проекту
Компонент
Властивість
Значення
Form1
Caption
Position
Буквы латынского алфавита
PoScreenCenter
Button1
Caption
Решение
Button2
Caption
Выход
StaticText1
Caption
BorderStyle
Font
Розмір
Накреслення
‘’
SbsSunken
полужирное
Зовнішній вигляд форми при виконанні програми наведено на рис. 3.3:
Рисунок 3.3 – Форма першого проекту під час виконання програми
Текст програми:
Procedure TForm1.Button1Click(Sender:Tobject);
var St:Char; So:String[80];
begin
So:=’’;
for st:=’A’ to ‘Z’ do
So:=So+St+’ ‘;
StaticText1.Caption:=So;
end;
Результат виконання програми: A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Приклад 2 Обчислити значення добутку для кінцевого числа співмножників. Значення числа співмножників ввести з клавіатури.
Встановимо на формі такі компоненти: три кнопки Button, п'ять компонентів Label, один компонент Edit. Один з компонентів Label використаємо для виведення. Форма при цьому має вигляд, поданий на рис. 3.4
Властивості встановлених компонентів, наведені в таблиці 3.2
Таблиця 3.2 – Властивості компонентів форми другого проекту
Компонент
Властивість
Значення
Form1
Caption
Position
Вычисление суммы конечного числа слагаемых
PoScreenCenter
Button1
Caption
TabOrder
Решение
Button2
Caption
Новое решение
Button3
Caption
Выход
Label1
Caption
Введите данные и нажмите кнопку «Решение»
Label2
Caption
N=
Label3
Caption
Результат
Edit1
Text
TabOrder
''
Label4
Caption
''
Рисунок 3.4 – Форма другого проекту під час виконання програми
Для встановлення початкових значень властивостей певних компонентів рекомендується використати подію для форми OnActivate і записати програму:
procedure TForm1.FormActivate(Sender: TObject);
Begin
Button1.Enabled:=False;
Label3.Hide; Label4.Hide;
end;
При запуску програми на формі видно лише пояснювальний напис і вікно Edit1. Кнопка Button1 (Рішення) стає недоступною. Це робиться для того, аби кнопкою можна було скористатися лише після введення значення для N.
Для забезпечення доступу до кнопки «Розв’язок», використовується подія OnChange для Edit1. Код для цієї події наведено нижче.
procedure TForm1.Edit1Change(Sender: TObject);
begin Button1.Enabled:=True; end;
Після введення даних можна використати подію OnClick по натисненню кнопки «Розв’язок». Код цієї події має вигляд
procedure TForm1.Button1Click(Sender: TObject);
var n:integer; Sn:String[20]; kod1:Integer;
pr:Real; Spr:String[20];
Begin
Sn:=Edit1.Text; Val(Sn,n,kod1);
if (kod1<>0) then
begin
ShowMessage('Данные введены неверно!'+#13+
'Повторите ввод!');
Edit1.Clear; Button1.Enabled:=False;
Edit1.SetFocus; exit;
end;
Label3.Show; Label4.Show;
Pr:=proiz(n);
Str(Pr:1:2,Spr);
Label4.Caption:='При N='+Sn+' произведение='+Spr;
end;
У наведеній підпрограмі події здійснюється контроль введеного значення і, якщо все правильно, висвічується допоміжне повідомлення в Label3, а результат обчислення виводиться в Label4. Для обчислення добутку здійснюється звернення до підпрограми функції, код якої записується в підпрограмі, розташованій в розділі Implementation. Результат виконання розрахунків наведено на рис.3.4. Схема алгоритму наведена на рис 3.5.
implementation
{$R *.DFM}
Function Proiz(n:Integer):Real;
var s,p:real; j,k:integer;
begin
p:=1;
Result=P
for k:=1 to n do
begin
s:=0;
for j:=k to n+1 do
if j=1 then Continue
else s:=s+(j+1)/(j-1);
if k=2 then Continue
else p:=p*(k-2)/(k+1)*s;
end;
result:=p;
end;
Рисунок 3.5. – Блок-схема алгоритму функції
Призначення кнопки «Новий розв’язок» полягає в тому, щоб забезпечити можливість введення нових значень. Код події для цієї кнопки наведено нижче:
procedure TForm1.Button2Click(Sender: TObject);
Begin
Edit1.Clear; Edit2.Clear; Edit1.SetFocus;
Edit2.Enabled:=False; Button1.Enabled:=False;
Label3.Hide; Panel1.Hide;
end;
Приклад 3 Обчислити суму кінцевого числа доданків ряду:
Встановимо на формі такі компоненти: три кнопки Button, чотири компоненти Label, два копоненти Edit і компонент Panel для виводу. Форма при цьому має вигляд, поданий на рис.3.6.
Рисунок 3.6. – Форма третього проекта
Властивості компонентів данної форми наведено в таблиці 3.3.
Таблиця 3.3 – Властивості компонентів форми третього проекту
Компонент
Властивість
Значення
Form1
Caption
Position
Вычисление суммы конечного числа слагаемых
PoScreenCenter
Для встановлення початкових значень властивостей певних компонентів рекомендовано використати подію для форми OnActivate і записати такий код події:
procedure TForm1.FormActivate(Sender: TObject);
Begin
Edit2.Enabled:=False; Button1.Enabled:=False;
Label3.Hide; Panel1.Hide;
end;
При запуску програми на формі видно лише пояснювальний напис і вікна Edit. Вікно Edit2 і кнопка Button1 (Рішення) стають неприступними. Це робиться для того, аби кнопкою можна було скористатися лише після введення значень для X і N. Аналогічно і для Edit2.
Для забезпечення доступу до вікна Edit2, а потім і до кнопки «Розв’язок», використовуються подія OnChange для Edit1 і Edit2. Коди для цих подій наведено нижче.
procedure TForm1.Edit1Change(Sender: TObject);
begin Edit2.Enabled:=True; end;
procedure TForm1.Edit2Change(Sender: TObject);
begin Button1.Enabled:=True; end;
Після введення даних можна використати подію OnClick по натисненні кнопки «Рішення». Код цієї події має наступний вигляд.
procedure TForm1.Button1Click(Sender: TObject);
var x:real;n:integer; Sx,Sn:String[20];
kod1,kod2:Integer;
sm:Real; Ssm:String[20];
Begin
Sx:=Edit1.Text; Sn:=Edit2.Text;
Val(Sx,x,kod1); Val(Sn,n,kod2);
if (kod1<>0) or (kod2<>0) then
Begin
ShowMessage('Данные введены неверно!'+#13+
'Повторите ввод!');
Edit1.Clear; Edit2.Clear;
Edit2.Enabled:=False; Button1.Enabled:=False;
Edit1.SetFocus;
Exit;
end;
Label3.Show; Panel1.Show;
Sm:=Sum(x,n);
Str(Sm:1:2,Ssm);
Panel1.Caption:='При х='+Sx+' и n='+Sn+' Сумма='+Ssm;
end;
У наведеній підпрограмі події здійснюється контроль введених значень і, якщо все правильно, висвічується допоміжне повідомлення в Label3, а результат обчислення виводиться на Panel1. Для обчислення суми здійснюється звернення до підпрограми-функції, код якої записується в підпрограмі, розташованій в розділі Implenentation.
Примітка: Для обчислення Х(2k+1) можна скористатися стандартною функцією IntPower(х, (2*к+1)), яка реалізована в бібліотеки Math.
Для приєднання цієї бібліотеки до програми необхідно в розділі Uses додати опис цієї бібліотеки, наприклад, у такий спосіб:
У цьому разі код підпрограми обчислення функції матиме вигляд:
Function Sum(x:Real;n:Integer):Real;
var s,a:Real; j,k:integer; Fakt:Real;
Begin
s:=0; Рисунок 3. 7.блок-схема
for k:=1 to n do функції Sum
begin
Fakt:=1;
for j:=1 to 2*k-1 do
Fakt:=Fakt*j;
a:=IntPower(x,(2*k+1));
s:=s+a/Fakt;
end;
Result:=s;
end;
Рисунок 3.8 – форма третього проекту під час виконання програми
Призначення кнопки «Новий розв’язок» полягає в тому, щоб забезпечити можливість введення нових значень.
Текст програми:
procedure TForm1.Button2Click(Sender: TObject);
Begin
Edit1.Clear; Edit2.Clear; Edit1.SetFocus;
Edit2.Enabled:=False; Button1.Enabled:=False;
Label3.Hide; Panel1.Hide;
end;
Приклад 4. Побудувати таблицю значень X та Y для наступної побудови графіка. Іншими словами, скласти програму табулювання функції y=f(x) при змінюванні х від а до b з кроком h.
Обчислення суми здійснюватимемо за рекурентними співвідношеннями за формулою:
Для розв’язання цієї задачі встановимо на формі такі компоненти: дві панелі Panel1, Panel2, на першій з яких відобразимо напис «АВН», а на другій «XY». Для введення значень «А, В, Н» встановимо три компоненти Edit: Edit1, Edit2, Edit3. Для виведення табулювання встановимо компонент Memo1. Для побудови графіка функції встановимо компонент Chart, розташований на вкладці «Additional». Для розв’язання задачі, підготовки нового розв’язку і для завершення роботи встановимо три кнопки: Button1, Button2 і Button3. Для пояснювальних написів встановимо три компоненти: Label1, Label2, Label3.
Властивості цих компонентів відображені в таблиці 3.4.
Таблиця 3.4 – Властивості компонентів форми четвертого проекту
Компонент
Властивість
Значення
Form1
Caption
Position
Табулирование функции и построение графика
PoScreenCenter
Button1
Caption
TabOrder
Решение
Button2
Caption
Новое решение
Button3
Caption
Выход
Label1
Caption
Введите данные и нажмите кнопку «Решение»
Label2
Caption
Результаты табулирования
Label3
Caption
График функции
Edit1
Text
TabOrder
''
Edit2
Text
TabOrder
''
Edit3
Text
TabOrder
''
Panel1
Caption
BorderStyle
A B H
BsSingle
Panel2
Caption
BorderStyle
X Y
BsSingle
Memo1
ScrollBars
SsVertical
Chart1
*
*Настроювання компонента описано нижче
Для того, щоб настроїти компонент Chart, двічі клацнемо на зображенні цього компонента. У діалоговому вікні, що з'явилося, клацнемо на кнопці Add вкладки Chart. У допоміжному діалоговому вікні вилучемо відображення «3D» і клацнемо на графіку «Line», після чого повернемося на вкладку «Chart» основного діалогового вікна. Для збільшення розміру відображення графіка на формі, вилучимо відображення «легенди», для чого перейшовши на вкладку «Legend», у вікні «Visible» вилучемо «галочку».
Перейшовши до закладки «Titles», вилучимо за допомогою клавіші «Backspase» напис «TChart». Компонент є готовий відображати графік функції. Вигляд форми після встановлення компонентів має вигляд, показаний на рис.3.9.
Рисунок 3.9. – Форма проекту “Табулювання функції”
Встановимо початкові значення властивостей певних компонентів в коді події для форми OnCreate, для чого двічі клацнемо на формі (з’явиться заготовка підпрограмми). Підпрограма цієї події має вигляд
procedure TForm1.FormCreate(Sender: TObject);
Begin
Label2.Hide; Label3.Hide; Panel2.Hide;
Memo1.Hide; Chart1.Hide;
Button1.Enabled:=False;
Edit2.Enabled:=False; Edit3.Enabled:=False;
end;
При запуску програми на формі видно лише пояснювальний напис і вікна Edit. Вікна Edit2, Edit3 і кнопка Button1 (Розв’зок) стають неприступними. Це робиться для того, аби кнопкою можна було скористатися лише після введення значень А, В і H. Для забезпечення доступу до вікна Edit2, потім Edit3 та до кнопки «Розв’зок» використовується подія OnChange для Edit1, Edit2 і Edit3. Текст програми:
procedure TForm1.Edit1Change(Sender: TObject);
Begin
Edit2.Enabled:=True;
end;
procedure TForm1.Edit2Change(Sender: TObject);
Begin
Edit3.Enabled:=True;
end;
procedure TForm1.Edit3Change(Sender: TObject);
Begin
Button1.Enabled:=True; end;
Після введення даних можна використати подію OnClick по натисненні кнопки «Розв’зок». Текст програми:
procedure TForm1.Button1Click(Sender: TObject);
var a,b,h:real;
k1,k2,k3:integer;
Begin
val(Edit1.Text,a,k1); val(Edit2.Text,b,k2);
val(Edit3.Text,h,k3);
If (k1<>0) or (k2<>0) or (k3<>0) then
begin
ShowMessage('Не все данные введены корректно!'+#13+
Табулювання функції виконано в підпрограмі-процедурі, яка реалізована в розділі Implementation. Текст підпрограми наведено нижче:
procedure TForm1.Tabul;
Const n=9;
var x,s,z:real; sx,ss:String[20];
i,k,m:integer;
Begin
Memo1.clear;
Series1.clear;
m:=Trunc((b-a)/h)+1;
for i:=1 to m do
begin
x:=a+(i-1)*h;
s:=0; z:=-0.5;
for k:=1 to n do
begin
z:=-z*x*x/(2*k-1)/(2*k);
Рисунок 3.10 Блок-схема функції Tabul
s:=s+z;
end;
str(x:8:2,sx); str(s:10:2,ss);
memo1.Lines.Add(' '+sx+' '+ss);
Series1.AddXY(x,s,'',clRed);
end;
end;
Слід звернути увагу на те, що в підпрограмі є звернення до компонентів Memo1 і Chart1(метод побудови графіка - Series1.AddXY). Для цього в розділі private оголошується підпрограма із вказанням параметрів:
procedure Tabul(a,b,h:real);
А заголовок підпрограми в розділі Implementation повинен мати вигляд:
Procedure TForm1.Tabul;
Призначення кнопки «Новий розв’зок» таке саме, що й в попередніх проектах, тобто забезпечувати можливість введення нових значень.
Рисунок 3.11.Вигляд програми під час виконання програми “Табулювання функції”
3 Контрольні запитання
1 Який процес називається циклічним?
2 Яке є призначення операторів циклу та які оператори циклу використовуються у мові Паскаль?
3 Чому дорівнює крок змінення параметра циклу в операторі For?
4 Які типи змінних можуть бути використані в якості параметра циклу, його початкового та кінцевого значеннь ?
5 Вкажіть помилки у таких фрагментах програм (всі змінні цілого типу) :
а) m:=2; n:=3; б) n:=-7; m:=2
for k:=1 to n do n:=n+m; for k:=n downto m do k:=k+1;
6 Чому дорівнює значення l після виконання фрагментів програми (всі змінні цілого типу) :
а) l :=1; б) l:=1; n:=–9
for k:=1 to 5 do m:=-3; for k:=n downto m do
for i:=1 to 10 do l:=l+1;
l:=l+1;
Лабораторне завдання
1 Вивчити основні теоретичні відомості лабораторної роботи й дати відповіді на контрольні запитання.
2 Скласти схему алгоритму і програму обчислення суми членів ряду, для чого при визначенні s використати рекуррентні співвідношення для здобуття наступного члена ряду (формула для обчислення s береться з табл. 4.1 згідно з номером прізвища студента в списку групи).
3 Скласти схему алгоритму і програму табулювання функції f(x), змінюючи x від 0,4 до 2,8 з кроком 0,2. При цьому функцію f(x) взяти функцію з табл. 4.1 згідно з заданим варіантом (ігноруючи в таблиці значення x).
4 За вказівкою викладача виконати на ЕОМ один чи обидва пункти 2, 3 даного завдання.
Таблиця 3.5 – Індивідуальні завдання
1
3
5
6
8
9
10
12
13
14
15
16
17
18
19
21
22
23
24
25
26
27
28
29
30
Л а б о р а т о р н а р о б о т а № 4
Організація обчислень з використанням умовних операторів циклу
1 Мета роботи
Вивчити умовні оператори циклу While і Repeat. Набути навичок їхнього використання при складенні циклічних програм.