r07.pdf

(328 KB) Pobierz
Szablon dla tlumaczy
Rozdział 7.
Sterowanie przebiegiem
działania programu
Większość działań programu powiązanych jest z warunkowymi rozgałęzieniami i pętlami. W
rozdziale 4., „Wyrażenia i instrukcje”, poznałeś sposób, w jaki należy rozgałęzić działanie
programu za pomocą instrukcji if .
W tym rozdziale:
dowiesz się, czym są pętle i jak się z nich korzysta,
nauczysz się tworzyć różnorodne pętle,
poznasz alternatywę dla głęboko zagnieżdżonych instrukcji if - else .
Pętle
Wiele problemów programistycznych rozwiązywanych jest przez powtarzanie operacji
wykonywanych na tych samych danych. Dwie podstawowe techniki to: rekurencja (omawiana w
rozdziale 5., „Funkcje”) oraz iteracja. Iteracja oznacza ciągłe powtarzanie tych samych czynności.
Podstawową metodą wykorzystywaną przy iteracji jest pętla.
Początki pętli: instrukcja goto
W początkowym okresie rozwoju informatyki, programy były nieporadne, proste i krótkie. Pętle
składały się z etykiety, zestawu wykonywanych instrukcji i skoku.
W C++ etykieta jest zakończoną dwukropkiem nazwą ( : ). Etykieta może być umieszczona po
lewej stronie instrukcji języka C++, zaś skok odbywa się w wyniku wykonania instrukcji goto
(idź do) z nazwą etykiety. Ilustruje to listing 7.1.
Listing 7.1. Pętla z użyciem słowa kluczowego goto
0: // Listing 7.1
1: // Pętla z instrukcją goto
2:
3: #include <iostream>
4:
5: int main()
6: {
7: int counter = 0; // inicjalizujemy licznik
8: loop: counter ++; // początek pętli
9: std::cout << "Licznik: " << counter << "\n";
10: if (counter < 5) // sprawdzamy wartość
11: goto loop; // skok do początku
12:
13: std::cout << "Gotowe. Licznik: " << counter << ".\n";
14: return 0;
15: }
Wynik
Licznik: 1
Licznik: 2
Licznik: 3
Licznik: 4
Licznik: 5
Gotowe. Licznik: 5.
Analiza
W linii 7., zmienna counter (licznik) jest inicjalizowana wartością 0 . W linii 8 występuje
etykieta loop (pętla), oznaczająca początek pętli. Zmienna counter jest inkrementowana,
następnie wypisywana jest jej nowa wartość. W linii 10. sprawdzana jest wartość zmiennej. Gdy
jest ona mniejsza od 5 , wtedy instrukcja if jest prawdziwa i wykonywana jest instrukcja goto . W
efekcie wykonanie programu wraca do linii 8. Program działa w pętli do chwili, gdy, wartość
zmiennej counter osiągnie 5 ; to powoduje że program wychodzi z pętli i wypisuje końcowy
komunikat.
Dlaczego nie jest zalecane stosowanie instrukcji
goto?
Programiści unikają instrukcji goto , i mają ku temu znaczące powody. Instrukcja goto umożliwia
wykonanie skoku do dowolnego miejsca w kodzie źródłowym, do przodu lub do tyłu.
Nierozważne użycie tej instrukcji sprawia że kod źródłowy jest zagmatwany, nieestetyczny i
trudny do przeanalizowania, kod taki nazywany „kodem spaghetti”.
Instrukcja goto
Aby użyć instrukcji goto , powinieneś napisać słowo kluczowe goto , a następnie nazwę
etykiety. Spowoduje to wykonanie skoku bezwarunkowego.
Przykład
if (value > 10)
goto end;
if (value < 10)
goto end;
cout << "Wartosc jest rowna 10!";
end:
cout << "gotowe";
Aby uniknąć użycia instrukcji goto , opracowano bardziej skomplikowane, ściśle kontrolowalne
instrukcje pętli: for , while oraz do...while .
Pętle while
Pętla while (dopóki) powoduje powtarzanie zawartej w niej sekwencji instrukcji tak długo, jak
długo zaczynające pętlę wyrażenie warunkowe pozostaje prawdziwe. W przykładzie z listingu 7.1,
licznik był inkrementowany aż do osiągnięcia wartości 5. Listing 7.2 przedstawia ten sam program
przepisany tak, aby można było skorzystać z pętli while .
Listing 7.2. Pętla while
0: // Listing 7.2
1: // Pętla while
2:
3: #include <iostream>
4:
5: int main()
6: {
7: int counter = 0; // inicjalizacja warunku
8:
9: while(counter < 5) // sprawdzenie, czy warunek jest
spełniony
10: {
11: counter++; // ciało pętli
12: std::cout << "Licznik: " << counter << "\n";
13: }
14:
15: std::cout << "Gotowe. Licznik: " << counter << ".\n";
16: return 0;
17: }
Wynik
Licznik: 1
Licznik: 2
Licznik: 3
Licznik: 4
Licznik: 5
Gotowe. Licznik: 5.
Analiza
Ten prosty program demonstruje podstawy działania pętli while . Gdy warunek jest spełniony,
wykonywane jest ciało pętli. W tym przypadku w linii 9. sprawdzane jest, czy zmienna counter
(licznik) ma wartość mniejszą od 5 . Jeśli ten warunek jest spełniony (prawdziwy), wykonywane
jest ciało pętli: w linii 11. następuje inkrementacja licznika, zaś jego wartość jest wypisywana w
linii 12. Gdy warunek w linii 9. nie został spełniony (tzn. gdy zmienna counter ma wartość
większą lub równą 5 ), wtedy całe ciało pętli while (linie od 10. do 13.) jest pomijane i program
przechodzi do następnej instrukcji, czyli w tym przypadku do linii 14.
Instrukcja while
Składnia instrukcji while jest następująca:
while ( warunek )
instrukcja;
warunek jest wyrażeniem języka C++, zaś instrukcja jest dowolną instrukcją lub blokiem
instrukcji C++. Gdy wartością wyrażenia warunek jest true (prawda), wykonywana jest
instrukcja , po czym następuje powrót do początku pętli i ponowne sprawdzenie warunku.
Czynność ta powtarza się, dopóki warunek zwraca wartość true . Gdy wyrażenie warunek
ma wartość false , działanie pętli while kończy się i program przechodzi do instrukcji
następujących po pętli.
Przykład
// zliczanie do 10
int x = 0;
while (x < 10)
cout << "X: " << x++;
Bardziej skomplikowane instrukcje while
Warunek sprawdzany w pętli while może być złożony, tak jak każde poprawne wyrażenie języka
C++. Może zawierać wyrażenia tworzone za pomocą operatorów logicznych && (I), || (LUB)
oraz ! (NIE). Taką nieco bardziej skomplikowaną instrukcję while przedstawia listing 7.3.
Listing 7.3. Warunek złożony w instrukcji while
0: // Listing 7.3
1: // Złożona instrukcja while
2:
3: #include <iostream>
4: using namespace std;
5:
6: int main()
7: {
8: unsigned short small;
9: unsigned long large;
10: const unsigned short MAXSMALL=65535;
11:
12: cout << "Wpisz mniejsza liczbe: ";
13: cin >> small;
14: cout << "Wpisz duza liczbe: ";
15: cin >> large;
16:
17: cout << "mala: " << small << "...";
18:
19: // w każdej iteracji sprawdzamy trzy warunki
20: while (small < large && large > 0 && small < MAXSMALL)
21: {
22: if (small % 5000 == 0) // wypisuje kropkę co każde 5000
linii
23: cout << ".";
24:
25: small++;
26:
27: large-=2;
28: }
29:
30: cout << "\nMala: " << small << " Duza: " << large << endl;
31: return 0;
32: }
Wynik
Wpisz mniejsza liczbe: 2
Wpisz duza liczbe: 100000
mala: 2.........
Mala: 33335 Duza: 33334
Analiza
Ten program to gra. Podaj dwie liczby, mniejszą i większą. Mniejsza liczba jest zwiększana o
jeden, a większa liczba jest zmniejszana o dwa. Celem gry jest odgadnięcie, kiedy się „spotkają”.
Linie od 12. do 15. służą do wprowadzania liczb. W linii 20. rozpoczyna się pętla while , której
działanie będzie kontynuowane, dopóki spełnione są wszystkie trzy poniższe warunki:
1. Mniejsza liczba nie jest większa od większej liczby.
2. Większa liczba nie jest ujemna ani równa zeru.
3. Mniejsza liczba nie przekracza maksymalnej wartości dla małych liczb całkowitych
( MAXSMALL ).
W linii 23. wartość zmiennej small (mała) jest obliczana modulo 5 000. Nie powoduje to zmiany
wartości tej zmiennej; chodzi jedynie o to, że wartość 0 jest wynikiem działania modulo 5 000
tylko wtedy, gdy wartość zmiennej small jest wielokrotnością pięciu tysięcy. Za każdym razem,
gdy otrzymujemy wartość zero, na ekranie wypisywana jest kropka, przedstawiająca postęp
działań. W linii 25. następuje inkrementacja zmiennej small , zaś w linii 27. zmniejszenie
zmiennej large (duża) o dwa.
Jeżeli w pętli while nie zostanie spełniony któryś z trzech warunków, pętla kończy działanie, a
wykonanie programu przechodzi do linii 29., za zamykający nawias klamrowy pętli while .
UWAGA Operator reszty z dzielenia (modulo) oraz warunki złożone zostały opisane w rozdziale
3, „Stałe i zmienne.”
Zgłoś jeśli naruszono regulamin