C++: Pętla for
Pętla for w języku C++ jest jednym z podstawowych mechanizmów sterowania przepływem programu, umożliwiającym wykonanie określonego bloku kodu wielokrotnie. Charakteryzuje się ona jasną i zwięzłą składnią, która składa się z trzech głównych elementów: inicjalizacji, warunku i iteracji.
for (inicjalizacja; warunek; iteracja) {
instrukcje;
}
Inicjalizacja
Na tym etapie zwykle deklaruje się i inicjalizuje zmienną sterującą pętlą. Inicjalizacja wykonuje się tylko raz, przed pierwszym przejściem przez pętlę.
for (int i = 0; ...)
W tym przykładzie int i = 0
jest częścią inicjalizacyjną, gdzie zmienna i
jest inicjalizowana wartością 0.
Warunek
Jest to wyrażenie logiczne, które jest sprawdzane przed każdym przejściem przez pętlę. Jeśli warunek jest spełniony (prawdziwy), pętla jest kontynuowana; jeśli nie, pętla kończy swoje działanie.
for (...; i < 10; ...)
Tutaj i < 10
jest warunkiem, który określa, że pętla będzie kontynuowana, dopóki wartość i
jest mniejsza niż 10.
Iteracja
Ostatni element pętli for, który jest wykonany po każdym przejściu przez pętlę. Najczęściej jest to instrukcja, która modyfikuje zmienną sterującą, tak aby ostatecznie doprowadzić do zakończenia pętli.
for (...; ...; i++)
W tym przypadku i++
jest instrukcją iteracyjną, która zwiększa wartość i
o 1 po każdym przejściu przez pętlę.
Zastosowanie pętli for
Przejdźmy do pierwszego przykładu, w którym wypiszemy liczby od 100 do 1000. Ręczne wypisanie tylu cout byłoby nieco nieefektywne i czasochłonne.
for (int i = 100; i < 1001; i++) {
cout << i << " ";
}
Jak widzisz wypisujemy wartość zmiennej i. Początkowa jej wartość to 100, a z każdym obiegem pętli zwiększa się ona o 1. Pętla działa dopóki zmienna i nie przekroczy 1000. Warto rozważyć czy dla Ciebie lepszym rozwiązaniem będzie zapis warunku będzie, jak w przykładzie i < 1001 czy i <= 1000. Działa tak samo, oznacza to samo, natomiast wybór sposobu zależy od indywidualnego podejścia.
W kolejnym przykładzie wypiszmy numery obiegów pętli.
for (int i = 1; i <= 5; i++) {
cout << "Iteracja " << i << endl;
}
Pętla wykona się pięć razy, za każdym razem wypisując na ekran numer iteracji, każda w osobnej linii.
To może jakiś bardziej złożony przykład? Załóżmy, że chcemy wypisać na ekran 10 pierwszych elementów ciągu liczbowego, którego pierwszym elementem będzie 5, natomiast każdy kolejny element będzie o 3 większy od poprzedniego.
#include <iostream>
using namespace std;
int main() {
int start = 5;
int roznica = 3;
cout << "Pierwsze 10 elementów ciągu: ";
for (int i = 0; i < 10; i++) {
cout << start + i * roznica << " ";
}
return 0;
}
Zmienna i w pętli jest naszym licznikiem elementów. Wykona się dokładnie 10 razy wypisujac kolejne elementy na ekran. Obliczenia naszego elementu do wypisania można dokonać w przeróżny sposób, natomiast w naszym przykładzie wykorzystaliśmy wartość początkową, którą zapisaliśmy w miennej start oraz różnicę, którą w każdym obiegu pętli mnożyliśmy przez zmienną i.
I tak w pierwszym obiegu pętli wartość i wynosi 0, różnicę mnożymy razy 0 i dodajemy do zmiennej start. Różnicy nie ma, więc wypisana zostaje wartość startowa: 5.
Kolejny obieg pętli. Różnicę mnożymy tym razem przez 1. Dodając obliczoną wartość do zmiennej start, otrzymujemy 5 + 1 * 3, z znając priorytety operatorów arytmetycznych, wiemy, że jest to zapis równoważny instrukcji 5 + ( 1 * 3 ), z której to otrzymujemy wynik 8. Zatem nasz wypisany na ekranie ciąg znaków, to na chwilę obecną:
5
8
Kolejne obiegi pętli, to kolejne obliczenia wartości wypisywanego na ekran elementu ciągu znaków. I tak kolejno otrzymujemy: 11, 14, 17, i tak dalej. Wypisujemy w ten sposób 10 pierwszych elementów ciągu.
Zagnieżdżanie pętli for
Język C++ umożliwia zagnieżdżanie jednej pętli for wewnątrz drugiej. Wymaga dokładności i uwagi, aby uniknąć błędów, takich jak nieskończone pętle czy wyczerpanie zasobów systemowych. Jeszcze przed nami tematy związane chociażby ze złożonością obliczeniową, ale warto sobie uzmysłowić, że gdy pojedyncza pętla wykona się 100 razy, to jeśli posiada wewnątrz siebie pętlę, która również wykonuje się 100 razy, to mówimy tu o 100 * 100, czyli 10 000 iteracji. To może nadal nie dużo, natomiast pokazuje skalę ewentualnego problemu. Przejdźmy zatem do przykładu.
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << i << ", " << j << endl;
}
}
Mamy tu dwie pętle for, jedna wewnątrz drugiej. Wykorzystano tu standardowe nazewnictwo zmiennych, pierwsza iteruje po i, natomiast druga po j.
W momencie uruchomienia pętli zewnętrznej, i ma wartość 0. Przechodzimy wówczas do wykonania instrukcji, czyli przejścia wszystkich obiegów pętli wewnętrznej, w której j przyjmie kolejno wartości 0, 1 oraz 2. Na ekran trafią zatem kolejno linie:
0, 0
0, 1
0, 2
Następnie program przejdzie do kolejnego obiegu pętli zewnętrznej. Całość powtórzy się z jedną tylko różnicą, tym razem zmienna i ma wartość 1.
1, 0
1, 1
1, 2
Po wykonaniu tych czynności pętla zewnętrzna przejdzie do ostatniego swojego obiegu. Program zakończy swoje działanie z wypisanymi na ekranie:
0, 0
0, 1
0, 2
1, 0
1, 1
1, 2
2, 0
2, 1
2, 2
Zmienne sterujące pętlą
Liczba całkowita. Najbardziej podstawowy i powszechnie używany typ zmiennej sterującej.
for (int i = 0; i < 5; i++) {
cout << "Liczba: " << i << endl;
}
Znak. Char może również być używany do iteracji przez znaki.
for (char c = 'a'; c <= 'e'; c++) {
cout << "Znak: " << c << endl;
}
W powyższym przykładzie pętla przejdzie i wypisze na ekan znaki od a do e.
Liczba zmiennoprzecinkowa. Mniej typowe, ale możliwe do użycia, gdy wymagana jest precyzja zmiennoprzecinkowa.
for (float f = 0.0; f < 1.0; f += 0.2) {
cout << "Wartość: " << f << endl;
}
W przykładzie wartość wypisywana na ekran rozpocznie się od 0.0, by w kazdym obiegu pętli zwiększać się o 0.2, dopóki pozostanie mniejsza niż 1.0. Tym samym ostatnia wypisana na ekran wartość będzie wynosiła 0.8.
Nieskończona pętla for
Nieskończona pętla for nie zawiera warunku zakończenia, bądź w przypadku chociażby błędu, zawiera ten warunek nieprawidłowy.
for(;;){
std::cout << ”Wypisuję to sobie w nieskończoność.” << std::endl;
}
Możemy świadomie skorzystać z takiej konstrukcji, wykorzystując do sterowania programem instrukcji takich jak: break czy continue.
break; – kończy wykonywanie pętli, powoduje przejście do linijki kodu położonej bezpośrednio za pętlą
continue; – przerywa obieg pętli, nie zostaną wykonane pozostałe linie danego obiegu pętli, przechodzimy od razu do kolejnego obiegu
Spójrzmy na przykład:
int a;
for(;;){
std::cout << ”Wprowadz liczbe”;
std::cin >> a;
if(a!=0){
std::cout << a;
continue;
std::cout << "Nigdy się nie wypiszę :(";
}
else{
break;
}
}
W naszym przykładzie wykorzystaliśmy pętlę nieskończoną, w której prosimy użytkownika o wprowadzenie liczby, wartości zmiennej a.
Następnie wykorzystujemy instrukcję warunkową, do sprawdzenia czy a jest różne od zera.
Jeżeli a jest różne od zera, wypisujemy jego wartość na ekran, następnie, dzięki instrukcji continue; przechodzimy do kolejego obiegu pętli i zaczynamy cały proces od nowa. W przeciwnym razie, a więc jeśli użytkownik wprowadził 0, kończymy pętlę.
Testy przypięte do lekcji | |
---|---|
Aby uzyskać dostęp do testów i ćwiczeń interaktywnych - Zaloguj się |