.::PĘTLE::.
Pętle(ang.loops),
zwane teżinstrukcjami
iteracyjnymi,
stanowią podstawę prawie
wszystkich
algorytmów. Lwia część zadań wykonywanych przez programy
komputerowe
opiera
się w całości lub częściowo właśnie na pętlach.
Liczba
takich powtórzeń (zwanychcyklamilubiteracjamipętli)
jest przy tym
ograniczona
w zasadzie tylko inwencją i rozsądkiem programisty. Te potężne
narzędzia
dają
więc możliwość zrealizowania niemal każdego algorytmu.
Pętle
są też niewątpliwie jednym z atutów C++: ich elastyczność i prostota jest
większa
niż
w wielu innych językach programowania.
Pętle
warunkowedoiwhile
Na
początek poznamy dwie konstrukcje, które zwane sąpętlami
warunkowymi.
Miano
to
określa całkiem dobrze ich zastosowanie: ciągłe wykonywanie kodu, dopóki
spełniony
jest
określonywarunek.
Pętla sprawdza go przy każdym swoim cyklu - jeżeli
stwierdzi
jego
fałszywość , natychmiast kończy działanie.
Pętlado
Prosty
przykład obrazujący ten mechanizm prezentuje się
następująco:
//
Do – pierwsza pętla warunkowa
#include<iostream>
#include<conio.h>
void
main()
{
int nLiczba;
do
{
std::cout
<<"Wprowadz
liczbe wieksza od 10:";
std::cin
>> nLiczba;
}
while
(nLiczba <= 10);
std::cout
<<"Dziekuje
za wspolprace :)";
getch(); }
Program
ten, oczekuje od nas o liczby większej niż dziesięć. Tym razem jednak nie daje
się zbyć byle czym - jeżeli nie będziemy skłonni od
razu
przychylić się do jego prośby, będzie ją niezłomnie powtarzał aż do skutku (lub
do
użycia
Ctrl+Alt+Del ;D).
Upór
naszej aplikacji bierze się oczywiście z umieszczonej wewnątrz niej pętlido(‘czyń
’).
Wykonuje
ona kod odpowiedzialny za prośbę do użytkownika tak długo, jak długo
ten
jest
konsekwentny w ignorowaniu jej :) Przejawia się to rzecz jasna
wprowadzaniem
liczb,
którenie
sąwiększe
od 10, lecz mniejsze lub równe tej wartości – odpowiada to
warunkowi
pętlinLiczba
<= 10.
Instrukcja niniejsza wykonuje się więc dopóty, dopóki
(ang.while)
zmiennanLiczba,
która przechowuje liczbę pobraną od użytkownika, nie
przekracza
granicznej wartości dziesięciu.
Co
się jednak dzieje przy pierwszym „obrocie” pętli, gdy program nie zdążył
jeszcze
pobrać
od użytkownika żadnej liczby? Jak moż na porównywać wartość zmiennejnLiczba,
która
na samym początku jest przecież nieokreślona?…
Tajemnica
tkwi w fakcie, iż pętla „do”dokonuje
sprawdzenia swojego warunkuna
końcukażdego
cyklu – dotyczy to także
pierwszego
z nich. Wynika z tego dość oczywisty wniosek:
Pętladowykonazawszeco
najmniej jeden przebieg.
Podsumowaniem
naszego spotkania z pętlądobędzie
jej składnia:
Do
{
instrukcje
}
while
(warunek)
Wystarczy
przyjrzeć się jej choć przez chwilę , by odkryć cały sens. Samo
tłumaczenie
wyjaśnia
właściwie wszystko: „Wykonuj (ang.do)instrukcje,
dopóki (ang.while)
zachodziwarunek”.
I to jest właśniespiritus
movenscałej
tej konstrukcji.
Pętlawhile
Przyszła
pora na poznanie drugiego typu pętli warunkowych, czyliwhile.
Słówko będące
jej
nazwą widziałeś już wcześniej, przy okazji pętlido–
nie jest to bynajmniej przypadek,
gdyż
obydwie konstrukcje są do siebie bardzo podobne.
Działanie
pętliwhileprześledzimy
zatem na poniższym ciekawym przykładzie:
//
While - druga pętla warunkowa
#include<iostream>
#include<ctime>
#include<conio.h>
void
main()
{
//
wylosowanie liczby
srand
((int) time(NULL));
int
nWylosowana = rand() % 100 + 1;
std::cout
<<"Wylosowano
liczbe z przedzialu 1-100."<<
std::endl;
//
pierwsza próba odgadnięcia liczby
int
nWprowadzona;
std::cout
<<"Sprobuj
ja odgadnac:";
std::cin
>> nWprowadzona;
//
kolejne próby, aż do skutku - przy użyciu pętli while
while
(nWprowadzona != nWylosowana)
{
if
(nWprowadzona < nWylosowana)
std::cout
<<"Liczba
jest zbyt mala.";
std::cout
<<"Za
duza liczba.";
std::cout
<<"
Spróbuj jeszcze raz:";
std::cin >> nWprowadzona; }
std::cout
<<"Celny
strzal :) Brawo!"<<
std::endl; getch();
}
Jest
to nic innego, jak prosta… gra :) Twoim zadaniem jest w niej
odgadnięcie
„pomyślanej”
przez komputer liczby (z przedziału od jedności do stu). Przy każdej
próbie
otrzymujesz
wskazówkę , mówiącą czy wpisana przez ciebie wartość jest za duża, czy
za
mała.
Tak
przedstawia się to w działaniu. Jako programiści chcemy jednak zajrzeć do
kodu
źródłowego
i przekonać się , w jaki sposób można było taki efekt osiągnąć.
Pierwszą
czynnością podjętą przez nasz program jest wylosowanie liczby,
którą
użytkownik
będzie odgadywał . Zasadniczo odpowiadają za to dwie początkowe
linijki:
srand
((int) time(NULL));
int
nWylosowana = rand() % 100 + 1;
Nie
będziemy obecnie zagłębiać się w szczegóły ich funkcjonowania, gdyż te
zostaną
omówione
w następnym rozdziale. Teraz możesz jedynie zapamiętać , iż pierwszy
wiersz,
zawierający
funkcjęsrand()(i
jej osobliwy parametr), jest czymś w rodzaju zakręcenia
kołem
ruletki. Jego obecność sprawia, że aplikacja za każdym razem losuje nam
inną
liczbę
.
Za
samo losowanie odpowiada natomiast wyrażenie z funkcjąrand().
Obliczona wartość
tego
że jest od razu przypisywana do zmiennejnWylosowanai
to o nią toczy bój
niestrudzony
gracz :)
Kolejny
pakiet kodu pozwala na wykonanie pierwszej próby odgadnięcia
właściwego
wyniku.
Nie widać tu żadnych nowości – z podobnymi fragmentami spotykaliśmy się
już
wielokrotnie
i wyjaśniliśmy je dogłębnie. Zauważmy tylko, że liczba wpisana
przez
użytkownika
jest zapamiętywana w zmiennejnWprowadzona.
O
wiele bardziej interesująca jest dla nas pętlawhile,
występująca dalej. To na niej
spoczywa
zadanie wyświetlania graczowi wskazówek, umożliwiania mu kolejnych prób
i
sprawdzania
wpisanych wartości.
Podobnie
jak w przypadkudo,
wykonywanie tej pętli uzależnione jest spełnieniem
określonego
kryterium. Tutaj jest nim niezgodność między liczbą wylosowaną
na
początku
(zawartą w zmiennejnWylosowana),
a wprowadzoną przez użytkownika (zmiennanWprowadzona).
Zapisujemy to w postaci warunkunWprowadzona
!=
nWylosowana.
Oczywiście pętla wykonuje się do chwili, w której założenie to
przestaje
być
prawdziwe, a użytkownik poda właściwą liczbę .
Wewnątrz
bloku pętli podejmowane zaś są dwie czynności. Najpierw wyświetlana
jest
podpowiedź
dla użytkownika. Mówi mu ona, czy wpisana przed chwilą liczba jest
większa
czy
mniejsza od szukanej. Gracz otrzymuje następnie kolejną szansę na
odgadnięcie
pożądanej
wartości.
Gdy
wreszcie uda mu się ta sztuka, raczony jest w nagrodę
odpowiednim
komunikatem
:)
Tak
oto przedstawia się funkcjonowanie powyższego programu przykładowego,
którego
witalną
częścią jest pętlawhile.
Wcześniej natomiast zdążyliśmy się dowiedzieć i
przekonać,
iż konstrukcja ta bardzo przypomina poznaną poprzednio pętlędo.
Na czym
więc
polega różnica między nimi?…
Jest
nią mianowiciemoment
sprawdzania warunkupętli.
Jak pamiętamy,doczyni
to
na
końcu każdego cyklu. Analogicznie,whiledokonuje
tego zawszena
początkuswego
przebiegu.
Determinuje to dość oczywiste następstwo:
Pętlawhilemoże
nie wykonać sięani
razu,
jeżeli jej warunek będzie od początku nieprawdziwy.
W
naszym przykładowym programie odpowiada to sytuacji, gdy gracz od razu trafia
we
właściwą
liczbę. Naturalnie, jest to bardzo mało prawdopodobne (rzędu 1%), lecz
jednak
możliwe.
Trzeba zatem przewidzieć i odpowiednio zareagować na taki przypadek, zaś pętlawhilerozwiązuje
nam ten problem praktycznie sama :)
Na
koniec tradycyjnie już przyjrzymy się składni omawianej
konstrukcji:
while
(warunek)
{
instrukcje
}
Ponownie
wynika z niej praktycznie wszystko: „Dopóki (while)
zachodziwarunek,
wykonujinstrukcje”.
Czyż nie jest to wyjątkowo intuicyjne? ;)
***
Tak
oto poznaliśmy dwa typy pętli warunkowych – ich działanie, składnię i
sposób
używania.
Tym samym dostałeś do ręki narzędzia, które pozwolą ci tworzyć lepsze
i
bardziej
skomplikowane programy.