• Nie Znaleziono Wyników

Instrukcja for

W dokumencie Stworzone na Wikibooks, (Stron 60-63)

Instrukcje sterujące

9.1. INSTRUKCJE WARUNKOWE 59

9.2.2 Instrukcja for

printf ("Do zapłaty: %d\n", podatek);

}

9.2 Pętle

9.2.1 Instrukcja while

Często zdarza się, że nasz program musi wielokrotnie powtarzać ten sam ciąg instrukcji. Aby nie przepisywać wiele razy tego samego kodu można skorzystać z tzw. pętli. Pętla wykonuje się dotąd, dopóki prawdziwy jest warunek.

while (warunek) {

/* instrukcje do wykonania w pętli */

}

/* dalsze instrukcje */

Całą zasadę pętli zrozumiemy lepiej na jakimś działającym przykładzie. Załóżmy, że mamy obliczyć kwadraty liczb od  do . Piszemy zatem program:

#include <stdio.h>

int main () {

int a = 1;

while (a <= 10) { /* dopóki a nie przekracza 10 */

printf ("%d\n", a*a); /* wypisz a*a na ekran*/

++a; /* zwiększamy a o jeden*/

}

return 0;

}

Po analizie kodu mogą nasunąć się dwa pytania:

ˆ Po co zwiększać wartość a o jeden? Otóż gdybyśmy nie dodali instrukcji zwiększającej a, to warunek zawsze byłby spełniony, a pętla “kręciłaby” się w nieskończoność.

ˆ Dlaczego warunek to “a <= ” a nie “a!=”? Odpowiedź jest dość prosta. Pętla sprawdza warunek przed wykonaniem kolejnego “obrotu”. Dlatego też gdyby waru-nek brzmiał “a!=” to dla a= jest on nieprawdziwy i pętla nie wykonałaby ostatniej iteracji, przez co program generowałby kwadraty liczb od  do , a nie do .

9.2.2 Instrukcja for

Od instrukcji while czasami wygodniejsza jest instrukcja for. Umożliwia ona wpisanie usta-wiania zmiennej, sprawdzania warunku i inkrementowania zmiennej w jednej linijce co czę-sto zwiększa czytelność kodu. Instrukcję for czę-stosuje się w następujący sposób:

9.2. PĘTLE 61

for (wyrażenie1; wyrażenie2; wyrażenie3) { /* instrukcje do wykonania w pętli */

}

/* dalsze instrukcje */

Jak widać, pętla for znacznie różni się od tego typu pętli, znanych w innych językach programowania. Opiszemy więc, co oznaczają poszczególne wyrażenia:

ˆ wyrażenie — jest to instrukcja, która będzie wykonana przed pierwszym przebiegiem pętli. Zwykle jest to inicjalizacja zmiennej, która będzie służyła jako “licznik” przebie-gów pętli.

ˆ wyrażenie — jest warunkiem zakończenia pętli. Pętla wykonuje się tak długo, jak prawdziwy jest ten warunek.

ˆ wyrażenie — jest to instrukcja, która wykonywana będzie po każdym przejściu pętli.

Zamieszczone są tu instrukcje, które zwiększają licznik o odpowiednią wartość.

Jeżeli wewnątrz pętli nie ma żadnych instrukcji continue (opisanych niżej) to jest ona równoważna z:

{

wyrażenie1;

while (wyrażenie2) {

/* instrukcje do wykonania w pętli */

wyrażenie3;

} }

/* dalsze instrukcje */

Ważną rzeczą jest tutaj to, żeby zrozumieć i zapamiętać jak tak naprawdę działa pętla for.

Początkującym programistom nieznajomość tego faktu sprawia wiele problemów.

W pierwszej kolejności w pętli for wykonuje sięwyrażenie1. Wykonuje się ono zawsze, nawet jeżeli warunek przebiegu pętli jest od samego początku fałszywy. Po wykonaniu

wyrażenie1 pętla for sprawdza warunek zawarty wwyrażenie2, jeżeli jest on prawdziwy, to wykonywana jest treść pętli for, czyli najczęściej to co znajduje się między klamrami, lub gdy ich nie ma, następna pojedyncza instrukcja. W szczególności musimy pamiętać, że sam średnik też jest instrukcją — instrukcją pustą. Gdy już zostanie wykonana treść pętli for, na-stępuje wykonaniewyrażenie3. Należy zapamiętać, że wyrażenie zostanie wykonane, nawet jeżeli był to już ostatni obieg pętli. Poniższe  przykłady pętli for w rezultacie dadzą ten sam wynik. Wypiszą na ekran liczby od  do .

for(i=1; i<=10; ++i){

printf("%d", i);

}

for(i=1; i<=10; ++i) printf("%d", i);

for(i=1; i<=10; printf("%d", i++ ) );

Dwa pierwsze przykłady korzystają z własnościstruktury blokowej, kolejny przykład jest już bardziej wyrafinowany i korzysta z tego, że jakowyrażenie3może zostać podane dowolne bardziej skomplikowane wyrażenie, zawierające w sobie inne podwyrażenia. A oto kolejny program, który najpierw wyświetla liczby w kolejności rosnącej, a następnie wraca.

#include <stdio.h>

int main() {

int i;

for(i=1; i<=5; ++i){

printf("%d", i);

}

for( ; i>=1; i--){

printf("%d", i);

}

return 0;

}

Po analizie powyższego kodu, początkujący programista może stwierdzić, że pętla wy-pisze123454321. Stanie się natomiast inaczej. Wynikiem działania powyższego programu będzie ciąg cyfr12345654321. Pierwsza pętla wypisze cyfry “”, lecz po ostatnim swoim obiegu pętla for (tak jak zwykle)zinkrementuje zmiennąi. Gdy druga pętla przystąpi do pracy, zacznie ona odliczać począwszy od liczby i=, a nie . By spowodować wyświetlanie liczb od  do  i z powrotem wystarczy gdzieś między ostatnim obiegiem pierwszej pętli for a pierwszym obiegiem drugiej pętli for zmniejszyć wartość zmiennejio .

Niech podsumowaniem będzie jakiś działający fragment kodu, który może obliczać war-tości kwadratów liczb od  do .

#include <stdio.h>

int main () {

int a;

for (a=1; a<=10; ++a) { printf ("%d\n", a*a);

}

return 0;

}

W kodzie źródłowym spotyka się często inkrementacjęi++. Jest to zły zwyczaj, biorący się z wzorowania się na nazwie języka C++. Post-inkrementacjai++powoduje, że tworzony jest obiekt tymczasowy, który jest zwracany jako wynik operacji (choć wynik ten nie jest nigdzie czytany). Jedno kopiowanie liczby do zmiennej tymczasowej nie jest drogie, ale w pętli “for” takie kopiowanie odbywa się po każdym przebiegu pętli. Dodatkowo, w C++ po-dobną konstrukcję stosuje się do obiektów — kopiowanie obiektu może być już czasochłonną czynnością. Dlatego w pętli “for” należy stosować wyłącznie++i.

9.2.3 Instrukcja do..while

Pętle while i for mają jeden zasadniczy mankament — może się zdarzyć, że nie wykonają się ani razu. Aby mieć pewność, że nasza pętla będzie miała co najmniej jeden przebieg musimy zastosować pętlę do while. Wygląda ona następująco:

9.2. PĘTLE 63

do {

/* instrukcje do wykonania w pętli */

} while (warunek);

/* dalsze instrukcje */

Zasadniczą różnicą pętli do while jest fakt, iż sprawdza ona warunek pod koniec swojego przebiegu. To właśnie ta cecha decyduje o tym, że pętla wykona się co najmniej raz. A teraz przykład działającego kodu, który tym razem będzie obliczał trzecią potęgę liczb od  do .

#include <stdio.h>

int main () {

int a = 1;

do {

printf ("%d\n", a*a*a);

++a;

} while (a <= 10);

return 0;

}

Może się to wydać zaskakujące, ale również przy tej pętli zamiast bloku instrukcji można zastosować pojedynczą instrukcję, np.:

#include <stdio.h>

int main () {

int a = 1;

do printf ("%d\n", a*a*a); while (++a <= 10);

return 0;

}

W dokumencie Stworzone na Wikibooks, (Stron 60-63)