7. Instrukcje sterujące

7.6. Pętle o zadanej liczbie iteracji

Teoretycznie bardziej skomplikowaną niż omawiane wcześniej pętlą jest pętla o zadanej liczbie iteracji. Zazwyczaj taka pętla musi mieć zmienną sterującą, w wielu językach programowania w momencie wejścia do pętli musi być znana i ustalona liczba iteracji. W C++ oba te stwierdzenia są nieprawdziwe. Pętla for nie musi mieć zmiennej sterującej, inkrementowanej / dekrementowanej co krok. Liczba iteracji także nie musi być znana przed rozpoczęciem pętli – może się zmieniać w trakcie wykonywania pętli … Zwyczajowo stosuje się ją jako pętlę o zadanej liczbie iteracji, lecz nic nie stoi na przeszkodzie by tą pętlę wykorzystać analogicznie do while czy do-while.

Składnia wygląda następująco:


for (inicjalizacja; wyrazenie_warunkowe; krok)
  // instrukcja wykonywana w pętli
  instrukcja_w_petli();

Każdy z wymienionych elementów (inicjalizacja, wyrażenie_warunkowe, krok) są niezależnymi wyrażeniami / instrukcjami, każde z nich może zostać pominięte. Moment wykonania każdej z instrukcji wygląda następująco:

  • inicjalizacja – instrukcja wykonywana przed pierwszym przebiegiem pętli. Zwyczajowo znajduje się tutaj definicja i inicjacja zmiennej sterującej.
  • wyrażenie_warunkowe – instrukcja / wyrażenie warunkujące wykonanie kolejnego przejścia pętli, przy czym pętla może nie zostać wykonana ani razu. Jeśli pominiemy ten element – pętla nigdy się nie zakończy. Zwyczajowo umieszcza się tutaj wyrażenie testujące zmienną sterującą na okoliczność zakończenia pętli
  • krok – instrukcja wykonywana po każdym wykonaniu pętli. Zwyczajowo tutaj znajduje się inkrementacja zmiennej sterującej.

W przypadku pominięcia wszystkich wyżej wymienionych elementów uzyskamy pętlę nieskończoną.

Tok wykonania pętli for pokazujemy na rysunku poniżej:

W nowszych standardach C++ jest jeszcze jedna postać pętli for - tzw. pętla zakresowa, lub for-each, czyli dla każdego z kolekcji. Ta pętla upraszcza składnię w przypadku przeglądania wszystkich elementów z jakiejś kolekcji:


for (typ nazwaZmiennej : kolekcja) {
  // Instrukcje do wykonania
}

Przykładowo - poniższy kod wyświetli wszystkie elementy z tablicy:


int mojeNum[5] = {10, 20, 30, 40, 50};
for (int i : mojeNum) {
  cout << i << "\n";
}

W przypadku pętli zakresowej - jeśli chcemy zmieniać wartość elementu w kolekcji, często stosujemy referencję jako typ zmiennej elementu - inaczej zmienialibyśmy kopię a nie oryginał:


for (int i : mojeNum) {
  i += 2; // wartości w tablicy nie są zmieniane
}

for (int& i : mojeNum) {
  i += 2; // wartości są zmieniane - mamy referencję
}