Pętle w Arduino – for, while czy do…while? Którą wybrać?

Pętle w Arduino pozwalają wielokrotnie wykonywać ten sam fragment programu. Do wyboru są trzy podstawowe konstrukcje języka C++: for, while oraz do...while. Każda może doprowadzić do podobnego wyniku, ale różnią się sposobem określania liczby powtórzeń i momentem sprawdzania warunku.

Najprostsza zasada brzmi: użyj for, gdy znasz liczbę powtórzeń; while, gdy działanie ma trwać do spełnienia warunku; a do...while, gdy blok musi zostać wykonany przynajmniej raz. Poniższe porównanie pomoże wybrać właściwą pętlę i uniknąć blokowania programu.

Pętle w Arduino — którą wybrać?

SytuacjaNajlepszy wybórDlaczego?
Znasz liczbę powtórzeńforLicznik, warunek i jego zmiana znajdują się w jednym miejscu.
Nie znasz liczby powtórzeń, a warunek może od początku być fałszywywhileWarunek jest sprawdzany przed pierwszym wykonaniem bloku.
Blok musi wykonać się co najmniej razdo...whileWarunek jest sprawdzany dopiero na końcu.
Arduino ma jednocześnie reagować na przycisk, mierzyć czas i sterować wyjściamiloop() i millis()Długa pętla oczekująca mogłaby zatrzymać pozostałe zadania.

Szybka decyzja: znasz liczbę obiegów — wybierz for. Nie znasz jej — sprawdź, czy kod ma wykonać się obowiązkowo jeden raz. Jeśli tak, wybierz do...while; jeśli nie, wybierz while.

Czym różnią się for, while i do…while?

Cechaforwhiledo...while
Typowe zastosowanieZnana liczba powtórzeńPowtarzanie zależne od warunkuWykonanie przynajmniej raz
Sprawdzenie warunkuPrzed każdym obiegiemPrzed każdym obiegiemPo każdym obiegu
Minimalna liczba wykonań001
Miejsce zmiany licznikaZwykle w nagłówkuWewnątrz bloku lub przed nimWewnątrz bloku lub przed nim
Średnik po warunkuNieNieTak

Wybór pętli wpływa przede wszystkim na czytelność kodu. W wielu przypadkach program można przepisać z jednej konstrukcji na inną bez zmiany rezultatu, ale warto wybrać zapis, który najlepiej pokazuje zamiar autora.

Ten sam przykład zapisany trzema sposobami

Każda z poniższych symulacji wypisuje w Monitorze portu szeregowego liczby od 0 do 10. Uruchom je kolejno i porównaj kod, sposób sterowania licznikiem oraz wynik działania.

Pętla for

Symulacja_1 — pętla for: liczby od 0 do 10

To najbardziej naturalny zapis, ponieważ liczba obiegów jest znana. Deklaracja licznika, warunek i inkrementacja znajdują się w jednym nagłówku. Szczegółowe omówienie znajdziesz w lekcji pętla for w Arduino.

Pętla while

Symulacja_2 — pętla while: liczby od 0 do 10

Pętla daje ten sam wynik, ale trzeba samodzielnie utworzyć licznik i pamiętać o jego zmianie. Gdyby zabrakło instrukcji i++, warunek pozostałby prawdziwy i program nie opuściłby pętli.

Pętla do…while

Symulacja_3 — pętla do…while: liczby od 0 do 10

Ta symulacja również wypisze liczby od 0 do 10. Ponieważ warunek początkowy jest prawdziwy, rezultat wygląda podobnie jak dla while. Różnicę widać dopiero wtedy, gdy warunek jest fałszywy jeszcze przed pierwszym obiegiem.

while i do…while przy fałszywym warunku

Uruchom poniższą symulację. Zmienna i ma wartość 0, a sprawdzany warunek to i > 1. Pętla while nie wykona się ani razu, ponieważ najpierw sprawdza warunek. Pętla do...while najpierw wykona swój blok, dlatego pokaże jeden wynik mimo fałszywego warunku.

Symulacja_4 — while kontra do…while

Kiedy używać pętli for?

for najlepiej sprawdza się, gdy przed rozpoczęciem pętli wiadomo, ile razy ma zostać wykonana. Typowe zastosowania w Arduino to:

  • kolejne włączanie kilku diod LED,
  • przeglądanie elementów tablicy,
  • wykonywanie określonej liczby pomiarów,
  • generowanie serii impulsów,
  • wypełnianie lub zerowanie bufora danych.

Zmianę licznika zwykle realizują operatory ++ lub --. Jeżeli nie są jeszcze jasne, zobacz lekcję operatory inkrementacji i dekrementacji.

W C++ istnieje również skrócony zapis range-based for, który kolejno pobiera wartości z tablicy. Nadal jest to odmiana pętli for, a nie czwarty podstawowy rodzaj pętli.

Kiedy używać pętli while?

while wybierz wtedy, gdy liczba obiegów nie jest znana, ale można wskazać warunek kontynuowania. Może to być oczekiwanie na określony stan wejścia, przetwarzanie danych znajdujących się w buforze albo powtarzanie obliczeń do uzyskania oczekiwanego wyniku.

Warunek jest sprawdzany przed wejściem do bloku. Jeśli od początku ma wartość false, instrukcje wewnątrz pętli nie wykonają się ani razu. Więcej przykładów, w tym użycie break, continue i flag logicznych, zawiera lekcja pętla while i do…while w Arduino.

Kiedy używać pętli do…while?

do...while przydaje się, gdy operację trzeba wykonać przynajmniej jeden raz, zanim będzie można zdecydować o jej powtórzeniu. Przykładem jest pierwsze pobranie danych, próba nawiązania komunikacji albo wyświetlenie menu przed sprawdzeniem decyzji użytkownika.

Zapamiętaj: konstrukcja do...while kończy się średnikiem po nawiasie z warunkiem: } while (warunek);.

Funkcja loop() nie jest instrukcją pętli

W szkicu Arduino funkcja loop() jest automatycznie wywoływana ponownie po dojściu do końca. Nie jest jednak czwartym rodzajem pętli C++. To część mechanizmu środowiska Arduino, który w uproszczeniu wielokrotnie uruchamia zwykłą funkcję.

W wielu programach nie trzeba umieszczać w loop() dodatkowej nieskończonej pętli. Pozostawienie krótkiej, szybko kończącej się funkcji ułatwia równoległą obsługę przycisków, czujników, komunikacji i odmierzania czasu.

Ważne: długa pętla while może zatrzymać wykonywanie dalszych instrukcji w loop(). Jeżeli Arduino ma zajmować się kilkoma rzeczami naraz, zastosuj maszynę stanów i odmierzanie czasu opisane w poradniku Arduino millis() bez delay().

break, continue i pętle zagnieżdżone

Przerwanie pętli instrukcją break

Instrukcja break natychmiast kończy najbliższą pętlę. Jest przydatna, gdy podczas przeglądania danych znaleziono już szukany element albo wystąpił warunek wymagający wcześniejszego wyjścia.

Pominięcie obiegu instrukcją continue

continue pomija pozostałą część bieżącego obiegu i rozpoczyna następny. W pętli while trzeba uważać, aby przed wykonaniem continue została zmieniona wartość wpływająca na warunek. W przeciwnym razie łatwo utworzyć pętlę nieskończoną.

Pętle zagnieżdżone

Pętla może znajdować się wewnątrz innej pętli. Takie zagnieżdżenie wykorzystuje się między innymi przy obsłudze wierszy i kolumn matrycy LED. Trzeba jednak pamiętać, że liczba wykonań się mnoży: pętla wewnętrzna wykonana 10 razy w pętli zewnętrznej wykonywanej 20 razy da łącznie 200 obiegów.

Najczęstsze błędy w pętlach Arduino

  • Brak zmiany warunku — pętla while nigdy się nie kończy, ponieważ licznik lub flaga pozostają bez zmian.
  • Średnik zaraz po warunku — zapis while (warunek); tworzy pustą pętlę.
  • Przypisanie zamiast porównaniaif (stan = HIGH) przypisuje wartość; porównanie zapisuje się jako stan == HIGH.
  • Zły warunek graniczny — użycie <= zamiast < może spowodować wyjście poza zakres tablicy.
  • Blokowanie programu — oczekiwanie w długiej pętli uniemożliwia normalne wykonywanie pozostałych zadań.
  • Nadmierne zagnieżdżanie — kod staje się trudniejszy do zrozumienia, a liczba operacji szybko rośnie.

Podsumowanie wyboru pętli

Wybieraj for do pracy z licznikiem i znaną liczbą powtórzeń. Stosuj while, gdy dalsze działanie zależy od warunku sprawdzanego przed obiegiem. Sięgaj po do...while, jeśli blok musi wykonać się co najmniej raz. Jeżeli program ma stale obsługiwać wiele niezależnych zadań, nie zamykaj go w długiej pętli oczekującej — pozwól funkcji loop() wykonywać się szybko i steruj zadaniami za pomocą stanów oraz millis().

Najczęstsze pytania o pętle w Arduino

Która pętla jest najszybsza?

Przy równoważnych warunkach różnice wydajności między for i while zwykle nie mają praktycznego znaczenia. Kompilator często tworzy bardzo podobny kod wynikowy. Ważniejsze są czytelność programu i liczba operacji wykonywanych wewnątrz pętli.

Czy pętla while może zablokować Arduino?

Tak. Jeżeli warunek nigdy nie stanie się fałszywy, program nie wykona instrukcji umieszczonych za pętlą. Przerwania sprzętowe mogą nadal działać, ale zwykły kod znajdujący się dalej w loop() nie zostanie obsłużony.

Czy można umieścić pętlę for wewnątrz while?

Tak. Wszystkie rodzaje pętli można dowolnie zagnieżdżać. Instrukcja break zakończy wtedy tylko najbliższą pętlę, w której została wykonana.

Czy loop() zastępuje pętlę nieskończoną?

W typowym szkicu Arduino tak: środowisko ponownie wywołuje funkcję loop() po jej zakończeniu. Zwykle nie ma potrzeby dodawania wewnątrz niej konstrukcji while (true).


Następne kroki: przejdź do szczegółowych lekcji o pętli for oraz pętlach while i do…while, a następnie uruchom zawarte w nich przykłady.