PO wyk06 v1

background image

Zaawansowane sterowanie

programem

Działanie każdego większego programu opiera się na licznych skokach i
pętlach.

Wiele problemów rozwiązuje się poprzez wielokrotne operowanie na tych
samych danych.

Pętle

Iteracja to powtarzanie tej samej czynności.

Podstawową metodą iteracji są pętle.

Najstarszy rodzaj pętli goto

W początkach informatyki, pętla składała się z etykiety, instrukcji
wewnętrznych i skoku. W C++ etykieta to nazwa zakończona dwukropkiem ( :
). Etykieta musi występować w linii jako pierwsza. Instrukcja skoku składa się
ze słowa kluczowego goto i nazwy etykiety docelowej.

background image

Etykieta o nazwie loop
(wyznacza początek pętli).

Przykład:

Dlaczego nie wykorzystuje się instrukcji goto ?

Instrukcja ta pozwala na przejście do dowolnego miejsca w programie, do
przodu lub do tylu. Powoduje to ogromną komplikację programu, taki kod jest
bardzo trudny do czytania i analizy. Określa się go jako „program-
spaghetti”

Aby uniknąć stosowania goto, wprowadzono bardziej zaawansowane i spójne
instrukcje pętli:

for

,

while

do . . . while

.

Wykorzystanie tych instrukcji czyni kod dużo jaśniejszym, instrukcja goto jest
zbędna.

background image

Pętle while

Pętla while pozwala na powtarzanie sekwencji instrukcji tak długo, jak
warunek początkowy jest prawdziwy.

while ( warunek)
{
instrucje;
}

Przykład:

Najpierw sprawdzany
jest warunek, jeśli jest
on

prawdziwy,

to

wykonywane

instrukcje

w

pętli.

Kiedy warunek będzie
fałszywy (licznik nie
będzie mniejszy niż 5),
to cała treść pętli
zostanie pominięta.

background image

Złożona instrukcja while

Warunek w instrukcji while może być dowolnie złożonym wyrażeniem C+
+.

Może zawierać wyrażenia utworzone za pomocą operatorów logicznych
&& (and -logiczne "i"),  (or -logiczne "lub) i ! (not - negacja).

Przykład:Napisać program realizujący prostą grę. Podajemy dwie liczby,

mniejsza jest zwiększana w każdym kroku o jeden, natomiast druga
zmniejszana o 2. Celem gry jest odgadnięcie, kiedy się spotkają.

Pętla while jest tak długo powtarzana jak prawdziwe są
trzy warunki:

nMala nie jest większa niż nDuza

nDuza nie jest ujemna

nMala nie przekroczyła dopuszczalnego zakresu
MAXMALA

Obliczamy

resztę

z

dzielenia

zmiennej nMala przez 5000. Nie
zmienia to wartości zmiennej. Jeśli
jest ona wielokrotnością 5000, to
warunek jest spełniony i na ekranie
zostaje wypisana kropka.

background image

continue i break

Instrukcja continue oferuje taką możliwość powrócenia do początku pętli
while jeszcze przed zakończeniem aktualnego powtórzenia.
Instrukcja break pozwala na wyjście z pętli wcześniej, niż na to zezwoli
warunek. Przechodzi ona do instrukcji po pętli.

Przykład

Zmniejszanie będzie pominięte, gdy zmienna
nMala będzie wielokrotnością zmiennej nPomin.

Jeśli zmienna nDuza osiągnie wartość
zmiennej nCel to wyświetlany jest
komunikat i gra również się kończy.

Gra kończy się, gdy zmienna nMala
przyjmie większą wartość niż zmienna
nDuza.

Zadaniem użytkownika jest podać taką wartość
zmiennej nCel (odpowiednią dla zmiennej nDuza),
aby gra się zakończyła zanim zmienna nMala stanie
się większa niż nDuza.

background image

Instrukcje continue i break powinny być stosowane bardzo
rozważnie. Podobnie jak goto bardzo gmatwają one kod. Program
niespodziewanie przeskakuje w zupełnie inne miejsca. Nawet mała
pętla while może się stać całkowicie nieczytelna.

Przykład

Ponieważ

wartość

1

oznacza

prawdę, to zakończyć pętle może
jedynie instrukcja break.

Ten program działa, ale trudno nazwać go eleganckim. Jest to dobry przykład
użycia niewłaściwego narzędzia. To samo można osiągnąć poprzez
umieszczenie warunku zakończenia pętli w miejscu dla niego wyznaczonym -
w instrukcji while.

Nieskończone pętle, takie jak while (1) mogą spowodować zawieszenie
komputera w przypadku, w którym warunek zakończenia nigdy nie
zostanie spełniony.

background image

Pętle

do . . . while

Możliwe jest, że pętla while nie wykona się ani razu. Warunek w while
sprawdzany jest przed wykonaniem instrukcji w pętli, zatem jeśli jest on od
razu fałszywy, to pętla zostanie pominięta.

Przykład

Za

pierwszym

razem,

kiedy

użytkownik podał wartość 3, pętla
wykonała się trzykrotnie.

Za drugim razem, gdy użytkownik
podał wartość 0, pętla nie wykona się
ani razu.

Co zrobić, jeśli chcemy, aby program wypisał "Cześć!" przynajmniej
raz?

Pętla while nie daje takiej możliwości, ponieważ warunek wykonania
sprawdzany jest jeszcze przed wejściem do pętli. Pewnym rozwiązaniem jest
nadanie odpowiedniej wartości zmiennej licznik z wykorzystaniem instrukcji if
tuż przed pętlą while:

if (nLicznik < 1) //wymuś wartość minimalną
nLicznik=1;

background image

Pętla do. . . while gwarantuje, że instrukcje w pętli zostaną wykonane
przynajmniej raz. Warunek sprawdzany jest nie przed wykonaniem lecz po.

Przykład

Podobnie jak w pętli while także w pętli do. . . while można wykorzystywać
instrukcje break i continue.

Oba rodzaje pętli różnią się jedynie miejscem sprawdzania warunku, w
pętli while sprawdzany jest on przed wykonaniem instrukcji pętli,
natomiast w pętli do. . . while po wykonaniu instrukcji pętli.

do
{
instrukcje;
} while ( wyrażenie );

background image

Pętla for

Kiedy wykorzystuje się pętlę while, to zazwyczaj ustala się jakąś wartość
początkową, a w każdym kroku pętli sprawdza się warunek związany z tą
wartością i w jakiś sposób zmienia się ją wewnątrz pętli.

Przykład

Pętla for łączy w sobie trzy elementy działania pętli - inicjalizację,
sprawdzenie warunku i zmianę wartości.

Instrukcja for składa się ze słowa kluczowego for i pary nawiasów.
Wewnątrz nawiasów umieszcza się trzy instrukcje oddzielone średnikami.

background image

Uwaga:

pierwsze i trzecie wyrażenie może być dowolną poprawną

instrukcją C++. Natomiast drugie wyrażenie musi być wyrażeniem
zwracającym jakąś wartość.

for ( wyrażenie1; wyrażenie2; wyrażenie3 )
{
instrukcje ;
}

Pierwsze wyrażenie to inicjalizacja.
Można tu umieścić każdą poprawną
instrukcję C++ jednak zazwyczaj
umieszcza się inicjalizację zmiennej
kontrolującej wykonywanie pętli.

Drugie wyrażenie to sprawdzenie
warunku, tutaj może się znaleźć
dowolne, poprawne wyrażanie C++.
Spełnia ono taką samą rolę jak
warunek w pętli while.

Trzecie wyrażenie to jakaś akcja. Zazwyczaj umieszcza się tutaj
inkrementację albo dekrementację zmiennej kontrolującej pętlę, jednak
można tu wstawić dowolną poprawną instrukcję C++.

background image

Pętla for daje bardzo dużo możliwości i jest bardzo elastyczna. Trzy
niezależne operacje (inicjalizacja, sprawdzenie warunku, akcja) mogą
występować w bardzo wielu wariantach.
Pętla for działa według następującego schematu:

1. Wykonaj instrukcje inicjalizacji.

2. Wylicz wartość wyrażenia w warunku.

3. Jeśli warunek jest spełniony to wykonaj akcję i instrukcje

pętli.

W każdym kroku pętli powtarzane są punkty 2 i 3.

Przykład

background image

Bardzo często w jednej pętli inicjalizujemy wiele zmiennych, sprawdzamy
złożone warunki i wykonujemy wiele instrukcji. Instrukcje inicjalizacji i akcji
można w C++ zamienić na instrukcję wielokrotną oddzielając je przecinkami.
Przykład

Każde wyrażenie w pętli for może być puste (w szczególnym przypadku
wszystkie jednocześnie). Aby to osiągnąć należy wstawić średniki tam, gdzie
powinny być wyrażenia.

Jeżeli za pomocą pętli for chcecie uzyskać pętlę równoważną pętli while, to
trzeba pominąć pierwsze i trzecie wyrażenie.

while ( nLicznik < 10)

background image

Przykład

Ten szczególny program wygląda nieco absurdalnie. Jednak czasami, takie
instrukcje jak while (1) albo for ( ; ; ) znajdują swoje zastosowanie.

Inicjalizacja wykonana została
przed rozpoczęciem pętli for.

Warunek stopu pętli to
oddzielna instrukcja if.

background image

W instrukcji for można wykonać tak wiele operacji, że często nie potrzeba
żadnej treści pętli. W takim przypadku należy pamiętać o umieszczeniu znaku
średnika (oznaczającego instrukcję pusta) za instrukcją for (można go
umieścić w tej samej linii co instrukcja for, ale łatwo go wtedy przegapić).

Przykład

Zwróćmy uwagę, że nie
jest

to

dobrze

zaprojektowana instrukcja
for. Ostatnia instrukcja -
akcja

-

wykonuje

stanowczo

za

wiele

czynności. Lepiej by było
tak:

for ( int i = 0; i < 10; i++ )
{
cout << ” i: ” << i << endl;
}

W obydwu przypadkach osiągamy ten sam rezultat, jednak drugie
rozwiązanie jest bardziej eleganckie i czytelne.

background image

Zagnieżdżone pętle for

Pętle można dowolnie zagnieżdżać poprzez umieszczenie pętli w treści innej
pętli. Taka wewnętrzna pętla będzie wykonywana przy każdej iteracji pętli, w
której jest umieszczona (czyli pętli zewnętrznej).
Przykład

Ważne jest to, że w przypadku pętli
zagnieżdżonych, pętla wewnętrzna jest
wykonywana w każdej iteracji pętli
zewnętrznej.

background image

Instrukcja switch

Kombinacje instrukcji if oraz if. . . else, w przypadku głębokiego
zagnieżdżenia, mogą powodować spore zamieszanie.

C++ oferuje tutaj wygodne, alternatywne rozwiązanie. W przeciwieństwie do
instrukcji if, która potrafi rozpatrzyć tylko jedną wartość jednocześnie)
instrukcja switch pozwala na wyszczególnienie dowolnej liczby wartości.
Ogólny schemat instrukcji switch:

switch ( wyrażenie )
{
case wartość1 : instrukcje;
break;
case wartość2 : instrukcje;
break;
...
case wartość#n: instrukcje;
break;
default:

instrukcje;

}

wyrażenie to dowolne poprawne wyrażenie
C++

instrukcje to dowolne
poprawne instrukcje C++
(również bloki instrukcji)

Instrukcja switch oblicza wartość
podanego wyrażenia i porównuje z
wartościami podanymi przy case.
Zauważmy, że sprawdzana jest
tylko relacja równości, nie można
tu

możliwości

wykorzystania

innych relacji.

Jeśli któraś z wartości przy case
jest równa wartości wyrażenia to
program przechodzi do podanych
dalej instrukcji i wykonuje wszystko
do końca bloku switch tak długo,
aż napotka instrukcję break.

Jeśli żadna z wartości nie jest równa wartości wyrażenia to wykonywane są
instrukcje przy słowie kluczowym default. Jeśli nie określi się instrukcji
default i program nie odnajdzie pasującej wartości, to instrukcja switch nie
zrobi nic, zostanie pominięta.

background image

Bardzo ważne jest, że jeśli nie ma instrukcji break na końcu każdego case,
to program wykona wszystkie instrukcje od pasującego case aż do końca
switch (jeśli gdzieś niżej napotka break, to oczywiście przerwie
wykonywanie). Jeżeli decydujecie się na takie rozwiązanie, to pamiętajcie o
umieszczeniu odpowiedniego komentarza informującego o tym, że brak
break jest zamierzony.

Przykład

background image

Jest wiele różnych metod tworzenia pętli w C++:
while sprawdza warunek, jeśli jest on spełniony, to zostaje wykonana
treść pętli.
do ... while najpierw wykonuje instrukcje pętli, a dopiero potem sprawdza
warunek. for pozwala na jednoczesną inicjalizację wartości i sprawdzenie
warunku. Jeśli warunek jest spełniony, to wykonywana jest ostatnia instrukcja
w for (akcja), a następnie treść pętli. Przed każdą iteracją ponownie
sprawdzany jest warunek.
 Instrukcja goto jest raczej pomijana, ponieważ powoduje bezwarunkowy
skok do zupełnie innego miejsca w programie, co czyni go nieczytelnym
(program spaghetti).
 Instrukcja continue powoduje przejście do początku pętli while, do...
while
oraz for. Instrukcja break natychmiastowo przerywa wykonywanie
podanych pętli oraz switch.


Document Outline


Wyszukiwarka

Podobne podstrony:
PO wyk07 v1
postfix krok po kroku v1 1
PO wyk02 v1
Szkolenie Q Motion Controllers po polsku V1 2 3 11 2003
PO wyk04 v1
PO wyk01 v1
PO wyk05 v1
PO wyk12 v1
PO wyk08 v1
PO wyk07 v1
postfix krok po kroku v1 1
postfix krok po kroku v1 0
WR 1273252 v1 Skrypt po breaku 1
Rehabilitacja po endoprotezoplastyce stawu biodrowego
Systemy walutowe po II wojnie światowej
HTZ po 65 roku życia
Zaburzenia wodno elektrolitowe po przedawkowaniu alkoholu

więcej podobnych podstron