Оператори за цикъл
Оператор за цикъл do-while
1. Пример
Задача: Да се състави програма SUM3.CPP , която въвежда от клавиатурата три цели числа и отпечатва сумата им.
До момента ни е известно едно решение на тази задача – декларираме три променливи, въвеждаме трите числа, събираме ги и отпечатваме резултата. Тъй като в програмирането целта е не просто да напишем програмата, а да намерим оптималния от всички възможни варианти, продължаваме да търсим нови решения.
При създаване на програми се налага използване на страндартни способи, които са се утвърдили с времето и са особено подходящи в определена ситуация.
Когато се търси сума на повече от две числа е добре да се подходи по следният начин:
- Декларираме една допълнителна променлива, в която да запишем сумата на трите числа и приемаме, че първоначално тази променлива има стойност 0.
- Последователно въвеждаме всяко едно от трите числа и го добавяме към сумата веднага след въвеждането му.
- Отпечатваме получената сума.
Така описаната програма изглежда по следния начин:
#include<iostream.h>
void main()
{
int a, b, c, s=0;
cin>>a;
s+=a;
cin>>b;
s+=b;
cin>>c;
s+=c;
cout<<s<<endl;
}
Решението е интересно с това, че числата се въвеждат последователно и на всяка стъпка успяваме да определим сумата на въведените до момента числа.
Така оформена програмата си има и недостатък - с въвеждане на нова променлива заемаме по-голяма част от оперативната памет, необходима за програмата. Ето защо е добре да помислим за нейното доусъвършенстване.
Лесно можем да забележим, че всяка една от променливите се използва само в два последователни оператора – при прочитането и при добавянето и към сумата. В останалата част от програмата тези променливи не се използват. В този случай можем да се откажем от променливите b и c и вместо тях отново да използваме а.
#include<iostream.h>
int main()
{
int a, b, c, s=0;
cin>>a;
s+=a;
cin>>а;
s+=а;
cin>>а;
s+=а;
cout<<s<<endl;
}
Какво трябва да променим в програмата, ако търсим сумата на 4 числа, 5 числа ... 100 числа?
Колкото и трудоемко да е реализирането на програмата за по-голям брой числа, създаването и е възможно. Повече би ни затруднила задачата, ако предварително не ни е известен броя на числата.
Ако погледнем последната програма ще видим, че има два оператора, които се повтарят при всяко въвеждане на нова стойност на променливата:
cin>>а;
s+=а;
Ако имаме възможност да напишем програмата, така че да укажем на компютъра да повтаря тези два оператора определен брой пъти (примерно докато въведем числото 0), това би улеснило работата ни многократно. Повторението на едни и същи действия в една програма, се нарича цикъл. Едно от най-полезните възможности на компютрите е способността им многократно да изпълняват едни и същи действия, с едни и същи или различни стойности на изразите, които участват в тях. Всеки език за програмиране разполага със средства за задаване на такива повторения, които е прието да се наричат “оператори за цикъл”.
За да можем да организираме един цикъл трябва да можем да си отговорим на два основни въпроса:
- Какво се повтаря? - Това трябва да бъде едно или няколко действия, описани чрез допустими за езика за програмиране оператори. Всяко изпълнение на тези действията е прието да се нарича итерация.
- До кога се повтаря? - Това повтаряне на едни и същи действия не може да се извършва безкрайно, т.е. трябва ни условие (израз), което да може да прекъсне цикъла.
2. Синтаксис и семантика на оператор do-while
Задача: Да се състави програма, която въвежда от клавиатурата числа до въвеждане на 0, и отпечатва сумата им.
Решение:
Очевидно, тук ще се наложи многократно повторение на описаните в решението на предишната задача оператори:
cin>>а;
s+=а;
Освен това в условието на задачата е казано ясно до кога трябва да се извършат тези повторения: докато се въведе числото 0.
Като имаме предвид, че използваните променливи остават същите – програмата, която решава тази задача има следния вид.
//sum.cpp
#include <iostream.h>
int main()
{
int a,s=0;
do
{
cin>>а;
s+=а;
}
while(a!=0);
cout<<s<<endl;
}
Тук операторът do-while осигурява цикличното повторение на двата оператора
cin>>а;
s+=а;
докато променливата а е различна от 0.
Както и за всеки друг оператор и в този случай, ще опишем синтаксиса и семантиката му.
а) Синтаксис (правила за запис):
do оператор while (израз);
оператор – произволен оператор, който е прието да се нарича тяло на цикъла;
израз – условие, което определя до кога се повтаря тялото на цикъла. Тук могат да участват както аритметични, така и логически операции и логически отношения, описани по правилата за логически и аритметични изрази.
Забележка:Тялото на цикъла описва действието, което трябва да се повтаря. Ако се налага да се повтаря повече от едно действие, т. е. се използва повече от един оператор, повтарящите се оператори се обединяват в съставен оператор чрез заграждането им в {}.
б) Семантика (правила за изпълнение):
Операторът do P while (B);, където Р е оператор, а В е израз, се изпълнява по следния начин:
- изпълнява се Р;
- изчислява се стойността на израза В;
- ако стойността на В е различна от нула, т. е. истина, се преминава към изпълнение на P;
- ако стойността на В е нула, се изпълнява следващия оператор в програмата.
Като използваме този оператор за цикъл, да решим следната задача:
Задача. Да се състави програма, която въвежда числа от клавиатурата до въвеждане на нула и отпечатва броя на числата:
Решение:
Както вече беше казано, за да успеем да решим задачата, трябва да изясним двата основни момента:
Какво се повтаря? – по аналогия с предишната задача лесно се съобразява, че ще се повтарят две действия: въвеждането на число а и преброяването му. Самото преброяване ще се осъществи, като при прочитане на всяко число увеличаваме с 1 стойността на една цяла променлива br (много важно е да съобразим, че в началото на програмата на тази променлива трябва да се присвои стойност 0). След този анализ става ясно, че тялото на оператора за цикъл се състои от следните два оператора:
cin>>a;
br++;
До кога се повтаря? – тук израза, определящ до кога ще се изпълнява програмата, е зададен явно в условието на задачата, т. е. тялото на цикъла ще се повтаря докато въвежданото число е различно от 0. По-точно казано, в качеството на израз можем да използваме самата променлива а, чрез която се въвеждат числа от клавиатурата. Ако тя е ненулева, тялото на цикъла ще продължи да се изпълнява. В момента, в който се въведе 0, програмата ще продължи със следващия оператор, а следвайки условието, той трябва да извежда броя на въведените числа - br.
След тези уточнения, получаваме като решение на задачата следната програма:
//count.cpp
#include<iostream.h>
int main()
{
int a, br=0;
do
{
cin>>a;
br++;
}
while (a!=0);
cout<<”br=”<<br<<endl;
}
При тестване на програмата се оказва, че броят на числата е с 1 по-голям от действителния, т.е. програмата е преброила и числото 0. Ако решим, че числото 0 не трябва да бъде преброявано, трябва да помислим за промяна в решението, която ще го избегне.
//count1.cpp
#include<iostream.h>
int main()
{
int a, br=0;
do
{
cin>>a;
br++;
}
while (a!=0);
cout<<”br=”<<br-1<<endl;
}
в) Забележки (Правила на използване)
При използването на оператора за цикъл do-whileтрябва да спазваме следните основни правила:
- израза задължително се загражда в скоби;
- когато в тялото на цикъла трябва да са включени няколко оператора, те се заграждат с { }, т.е. използваме съставен оператор;
- управляващото условие трябва да се променя в тялото на цикъла;
- при създаването на програмите трябва да имаме предвид, че тялото на цикъла се изпълнява задължително поне веднъж.
Задачи
Задача 2. Да се състави програма MULT.CPP, която чете от клавиатурата цели числа, до въвеждане на числото 1, и отпечатва произведението им.
Примерен вход
3
-1
9
126
1
Примерен изход
-3402
Примерен вход
-13
2
0
1
Примерен изход
0
Решение:
От условието на задачата е видно, че при решението ще трябва да реализараме повторение така, че както и до сега трябва да си отговорим на следните въпроси:
- Какви величини са необходими за работата на програмата?
int a; //тази целочислена променлива ще използваме за последователното въвеждане на всяко едно от числата
long Р=1; //в тази променлива ще натрупваме произведението на числата.
Присвояваме и първоначална стойност 1, за да можем да умножаваме досегашната стойност на Р с поредното въведено число. Променливата е от тип long, защото произведението винаги е много по-голямо от числата, които умножаваме и може бързо да излезе извън границите на тип int.
- Какво се повтаря? – по аналогия с предишната задача, лесно се съобразява, че ще се повтарят две действия: въвеждането на число а и умножението на Р с това число, т.е. тялото на оператора за цикъл се състои от следните два оператора:
cin>>a;
Р*=а;
- До кога се повтаря? – тук израза, определящ до кога ще се изпълнява програмата, е зададен явно в условието на задачата, т. е. тялото на цикъла ще се повтаря, докато въвежданото число е различно от 1. В момента, в който се въведе 1, програмата ще продължи със следващия оператор, а следвайки условието, той трябва да извежда произведението на въведените числа Р. Условието за край на цикъла ще изглежда така:
(а!=1)
След тези уточнения можем да напишем решението на задачата (кода на програмата).
//mult.cpp
#include<iostream.h>
int main()
{
int a;
long long P=1;
do
{
cin>>a;
P*=a;
}
while(a!=1);
cout<<P<<endl;
}
Задача 2. Да се състави програма NEGATIV.CPP, която чете от клавиатурата цели числа до въвеждане на отрицателно число и отпечатва броя на въведените четни числа
Примерен вход
3
13
24
55
0
46
-8
Примерен изход
2
Упътване:
- Какви величини са необходими за работата на програмата?
int a; // за последователното въвеждане на всяко едно от числата
int br=0; //за броя на четните числа
- Какво се повтаря?
cin>>a; //въвежда се поредното число
if(a%2==0)br++; //ако въведеното число се дели на 2 без остатък , се увелечава броя на четните числа.
- До кога се повтаря?
Докато (а>=0).
III. Задачи за упражнение
Зад. 1.Посочете колко пъти ще се изпълни тялото на цикъла и кое ще бъде последното отпечатано число:
a) I=0; N=11
do
{
I=I+1;
cout<<I;
}
while (I<=N);
б) N=11; I=-5;
do
{
I=I+1;
cout<<I;
}
while (I<=N);
в) I=1;
do
I=I+2;
while (I!=18);
г) N=11; I=-5;
do
{
I=I-1;
cout<<I;
}
while (I<=N);
Зад. 2. Какъв е резултатът от изпълнението на следния програмен фрагмент?
do
cin>>a>>b>>c;
while (a+b>c && a+c>b && b+c>a);