Оператор за цикъл while
I. Теоретични бележки
1. Пример
Нека отново разгледаме една традиционна и вече позната задача.
Задача: Да се състави програма MAX3.CPP, която въвежда от клавиатурата три цели числа и отпечатва най-голямото от тях.
Вече намерихме начин на решение на тази задача и той е следния:
- Декларираме една допълнителна променлива m, в която да запишем максималното от трите числа.
- Въвеждаме първото число и приемаме, че то e максимално, с други думи го присвояваме на променливата m.
- Последователно въвеждаме всяко едно от останалите две числа и го сравняваме с m. Ако се окаже, че числото е по-голямо от m, то става максимално, т. е. променяме стойността на m, като и присвояваме стойността на новото число.
- Отпечатваме полученото максимално число.
#include<iostream.h>
void main()
{
int a, b, c, m;
cin>>a;
m=a;
cin>>b;
if(b>m)m=b;
cin>>c;
if(c>m)m=c;
cout<<m<<endl;
}
Лесно може да се забележи, че променливите b и c не са задължителни за правилната работа на програмата и могат да се заменят с променливата a, при което програмата ще добие следният вид:
//max3.cpp
#include<iostream.h>
void main()
{
int a, m;
cin>>a;
m=a;
cin>>a;
if(a>m)m=b;
cin>>a;
if(a>m)m=a;
cout<<m<<endl;
}
Също като при задачата за сумата забелязваме, че ако започнем да увеличаваме броя на числата, това просто ще доведе до увеличаване броя на повтарящите се оператори за въвеждане и проверка. Това означава, че можем да решим задачата по същия начин, стига да уточним двата основни въпроса:
- Какво се повтаря?
Отговорът в случая е - двата оператора:
cin>>a;
if(a>m)m=b;
- До кога се повтаря?
Това зависи от условието на задачата. Да решим следната задача:
Задача: Да се състави програма MAX.CPP, която въвежда от клавиатурата числа до въвеждане на 0 и отпечатва най-голямото от тях.
Така формулираното условие ни дава възможност да определим до кога ще се повтарят посочените по-горе оператори, а именно докато въвежданото число а е различно от 0.
Сега вече, използвайки знанията си за оператора за цикъл do-while, можем да решим задачата. Получаваме следната програма:
#include <iostream.h>
void main ( )
{
int a, m;
cin>>a;
m=a;
do
{
cin>>a;
if (m<a) m=a;
}
while (a);
cout<<”max=”<<m;
}
Вече знаем, че макар и да изглеждат перфектни на пръв поглед, програмите не винаги се държат коректно. Това особено важи когато става дума за някои по-специални случаи.
От решените преди това задачи с цикли, знаем, че при подобна формулировка на повторението, след въвеждане на 0, повторенията спират. Да тестваме и новата програма, като първо въведем числото 0. Ако програмата работи коректно, тя би трябвало да спре в този момент и да отпечата като най-голямо число 0. За съжаление забелязваме, че след въвеждане на 0, програмата продължава да изчаква въвеждането на второ число. След като още веднъж въведем 0, програмата вече наистина спира.
Подобен пропуск е непростим в програмирането и затова сега ще трябва да го отстраним. За целта трябва да открием на какво се дължи. След трасиране на програмата с помощта на клавиша F7, забелязваме, че първото число 0 се въвежда с оператора cin>>a;, който се намира извън тялото на цикъла. След присвояването m=a;, започва изпълнението на тялото на оператора за цикъл, което както вече споменахме винаги се изпълнява поне веднъж. Именно тогава се изисква второто въвеждане на 0, което се оказва излишно.
Ето защо, за да решим проблема, се налага да изключим възможността при първо число 0 цикъла да се изпълнява. Лесно се вижда, че ако поставим преди запазената дума do оператор за проверка, дали стойността на а е различна от 0, програмата вече ще работи коректно, т. е. цикълът ще започне да се изпълнява само ако първото въведено число не е 0.
Получава се следната (вече коректна) програма:
#include <iostream.h>
void main ( )
{
int a, m;
cin>>a;
m=a;
if(a)
do
{
cin>>a;
if (m<a) m=a;
}
while (a);
cout<<”max=”<<m;
}
Тук прави впечатление, че проверката за това, дали a е различно от 0, се прави веднъж от оператора if преди изпълнението на оператора за цикъл и след това отново при условието за край на цикъла. Това изглежда доста тромаво и неестествено. За щастие, в езика за програмиране С++ е предвиден специален оператор, при който тялото на цикъла може да не се изпълни нито веднъж.
Това е така наречения оператор за цикъл с предусловие while.
Операторът while позволява да се организира цикъл, т.е. многократно изпълнение на един или група последователни оператори. Наборът от последователни оператори записани след while образува тялото на цикъла. Продължителността на цикъла се управлява от условие за край на цикъла, включено в заглавието на оператора while.
За да можем правилно да използваме и този оператор, трябва да се запознаем с правилата за неговото записване (синтаксис) и с правилата за неговото изпълнение (семантика).
2. Синтаксис и семантика на оператор while
а) Синтаксис на оператора за цикъл с предусловие while (правила за запис):
while (израз) оператор;
оператор – произволен оператор, който е прието да се нарича тяло на цикъла;
израз – условие, което определя до кога се повтаря тялото на цикъла. Тук могат да участват както аритметични, така и логически операции и логически отношения, описани по правилата за логически и аритметични изрази.
Забележка:Тялото на цикъла описва действието, което трябва да се повтаря. Ако се налага да се повтаря повече от едно действие, т. е. се използва повече от един оператор, повтарящите се оператори се обединяват в съставен оператор чрез заграждането им в {}.
б) Семантика оператора while (правила за изпълнение):
Операторът while(B) P; където Р е оператор, а В е израз, се изпълнява по следния начин:
- изчислява се стойността на израза В;
- ако стойността на В е различна от нула, т. е. истина, се преминава към изпълнение на P;
- ако стойността на В е нула, се изпълнява следващия оператор в програмата.
в) Забележки (Правила на използване)
Както при използването на оператора за цикъл do-while и тук трябва да спазваме няколко основни правила:
- изразът задължително се загражда в скоби;
- когато в тялото на цикъла трябва да са включени няколко оператора, те се заграждат с { };
- управляващото условие трябва да се променя в тялото на цикъла;
- задължителна инициализация (даване на начални стойности) на условието на цикъла;
Освен това при създаването на програмите трябва да имаме предвид, че тялото на цикъла може да не се изпълни нито веднъж.
С помощта на оператора за цикъл while, решението на разгледаната по горе задача изглежда така:
//max.cpp
#include <iostream.h>
void main ( )
{
int a, m;
cin>>a;
m=a;
while (a)
{
cin>>a;
if (m<a) m=a;
}
cout<<”max=”<<m;
}
г) Прилики и разлики в операторите while и do-while
· прилики:
- и двата оператора имат тяло, което показва какво ще се повтаря;
- и двата оператора имат израз, който определя до кога ще се извършват повторенията.
· разлики:
- тялото на оператора while може да не се изпълни нито веднъж, докато тялото на do-while се изпълнява задължително поне веднъж;
- в do-while, след скобите на израза поставяме “;”, тъй като с това приключва оператора, докато при while след израза започва тялото на оператора.
Кой от двата оператора ще използваме в дадена ситуация зависи от условието на задачата, която решаваме в момента.
II. Задачи за упражнение:
Зад. 1. Посочете колко пъти ще се изпълни тялото на цикъла и кое ще бъде последното отпечатано число:
а) const N=11;
int I=0;
while (I<N)
{
I=I+1;
cout<<”I=”<<I;
}
б) const N=11;
int I=-5;
while (I<=N)
{
I++;
cout<<I;
}
в) I=7;
while (I<4)
I+=4;
cout<<I;
г) I=3;
while (I<4)
I--;
cout<<I;
д) const N=11;
int I=27;
while (I<N)
{
I-=1;
cout<<I;
}
Зад. 2. Да се състави програма, която чете от клавиатурата числа до въвеждане на 0 и извежда на екрана най-малкото въведено число.