Pętla repetycyjna
Pętla repetycyjna (pętla warunkowa) w programowaniu, to rodzaj pętli, w której wykonanie kolejnej iteracji uzależnione jest od pewnego, zdefiniowanego przez programistę warunku. Warunek zawarty w definiowanej pętli jest pewnym wyrażeniem, które zwraca wartość typu logicznego (np. Pascal[1][2], Visual Basic[3], VBA[4]). Istnieją języki programowania, w których składnia nie przewiduje takiego typu danych. W językach tych stosuje się wyrażenia zwracające pewną wartość innego typu, która następnie podlega odpowiedniej interpretacji, np. wartość zero może być utożsamiana z wartością false
typu logicznego, a pozostałe wartości z wartością true
, lub inne rozwiązania (np. PL/I[5][6], C[7][8][9][10], C++[9][11] i pochodne). W zależności do tego, czy wartość logiczna, uzyskana w wyniku ewaluacji wyrażenia reprezentującego warunek, jest równa wartości logicznej true
(prawda), czy false
(fałsz), wykonywanie pętli jest kontynuowane, bądź przerywane.
Wyrażenia warunkowe
edytujJak wyżej zaznaczono, pętla repetycyjna definiowana jest za pomocą określonego wyrażenia, które określa czy ma nastąpić przejście do kolejnej iteracji, czy też ma zostać zakończone wykonywane pętli i w konsekwencji ma nastąpić przejście do kolejnej instrukcji umieszczonej za daną pętlą. Zapis wyrażenia, oraz typ wartości wyrażenia, zależny jest od składni konkretnego języka programowania. Powszechnym jest zapis wyrażeń kontrolnych analogicznie do zapisu tych wyrażeń dla instrukcji warunkowej. Szczególne znaczenie mają w tym przypadku operatory porównań, choć warunek może zostać wyrażony także całkiem inaczej, np. jako wywołanie funkcji zwracającej wartość logiczną, bądź jako identyfikator zmiennej logicznej, której wcześniej przypisano rezultat ewaluacji wyrażenia warunkowego. Powszechna jest również w językach programowania dostępność operatorów logicznych, umożliwiających budowanie warunków złożonych z kilku warunków łącznych lub alternatywnych (ewentualnie mogą w konkretnym języku być dostępne inne operatory logiczne, np. alternatywy wykluczającej czy implikacji). Ponadto operator logiczny realizujący operację negacji pozwana na rekompensatę ewentualnego braku pętli powtarzanej przy spełnieniu lub niespełnieniu warunku, gdyż zastosowanie tego operatora do podanego warunku jest równoważne zastosowaniu frazy przeciwnej.
warunek złożony | użycie zmiennej | powtarzaj gdy warunek nie spełniony (sprawdzany na początku pętli) alternatywny wobec braku odpowiedniej instrukcji |
---|---|---|
while (a<b) and ((b>c) or (b>d)) do
begin
{ instrukcje pętli }
end;
|
var logic : Boolean;
begin
repeat
{ instrukcje pętli 1 }
logic:=(a<b) xor (b>c);
{ instrukcje pętli 2 }
until logic;
end.
|
while not (a>=b) do
begin
{ instrukcje pętli }
end;
|
Warunki kontynuacji bądź zaniechania wykonywania pętli
edytujW różnych językach programowania stosowane są warunki, które decydują o kontynuacji wykonywania pętli lub jej przerwania, w następujący sposób:
- pętla jest kontynuowana gdy warunek jest spełniony (
true
), a przerywana gdy nie (false
), lub odwrotnie - pętla jest kontynuowana gdy warunek nie jest spełniony (
false
), a przerywana gdy jest spełniony (true
).
miejsce sprawdzania warunku | przypadek | kod z użyciem pętli | kod "zastępczy" |
---|---|---|---|
sprawdzanie warunku na początku pętli | powtarzaj, gdy warunek spełniony |
Do While warunek
' treść pętli
Loop
|
start: If Not warunek Then Goto koniec
' treść pętli
Goto start
koniec: ' koniec pętli
|
powtarzaj, gdy warunek nie spełniony |
Do Until warunek
' treść pętli
Loop
|
start: If warunek Then Goto koniec
' treść pętli
Goto start
koniec: ' koniec pętli
| |
sprawdzanie warunku na końcu pętli | powtarzaj, gdy warunek spełniony |
Do
' treść pętli
Loop While warunek
|
start:
' treść pętli
If warunek Then Goto start
' koniec pętli
|
powtarzaj, gdy warunek nie spełniony |
Do
' treść pętli
Loop Until warunek
|
start:
' treść pętli
If Not warunek Then Goto start
' koniec pętli
|
Miejsce sprawdzania warunków
edytujWarunki decydujące o kontynuacji lub zaprzestaniu wykonywania pętli mogą być sprawdzane:
- na początku pętli, przed wykonaniem pierwszej instrukcji zawartej w bloku definiowanej pętli,
- wewnątrz pętli, w jej bloku, po wykonaniu części instrukcji, a przed wykonaniem pozostałych,
- na końcu pętli, po wykonaniu wszystkich instrukcji zawartych w bloku definiowanej pętli.
Jeżeli warunek jest sprawdzany na początku pętli, to może nastąpić taka sytuacja, że instrukcje zawarte w pętli nigdy nie zostaną wykonane. Będzie to miało miejsce w sytuacji, gdy przy pierwszym wykonaniu warunek nie będzie spełniony (lub odwrotnie, w zależności od rodzaju pętli – zobacz wyżej). Inaczej jest, gdy warunek jest sprawdzany na końcu pętli. W tym przypadku instrukcje zawarte w pętli zostaną wykonane co najmniej jeden raz. Natomiast, jeżeli warunek jest sprawdzany wewnątrz pętli mamy sytuację stanowiącą połączanie obu powyższych przypadków. Mianowicie instrukcje zapisane przed sprawdzeniem warunku, zostaną zawsze wykonane co najmniej jeden raz, a instrukcje zapisane po warunku sprawdzającym, mogą nie zostać wykonane ani jeden raz.
miejsce sprawdzania warunku | na początku | wewnątrz | na końcu | ||||||
---|---|---|---|---|---|---|---|---|---|
przykład |
#define MIN=4
int a;
scanf("a=%d",a);
while(MIN>=a)
{
printf("Teraz a=%d\n\r",a++);
printf("Teraz a=%d\n\r",a++);
}
|
#define MIN=4
int a;
scanf("a=%d",a);
while(1)
{
printf("Teraz a=%d\n\r",a++);
if (!(MIN>=a)) break;
printf("Teraz a=%d\n\r",a++);
}
|
#define MIN=4
int a;
scanf("a=%d",a);
do
printf("Teraz a=%d\n\r",a++);
printf("Teraz a=%d\n\r",a++);
while(MIN>=a)
| ||||||
wartość zmiennej a
|
1 | 3 | 5 | 1 | 3 | 5 | 1 | 3 | 5 |
wyniki | Teraz a=1 Teraz a=2 Teraz a=3 Teraz a=4 |
Teraz a=3 Teraz a=4 |
Teraz a=1 Teraz a=2 Teraz a=3 Teraz a=4 Teraz a=5 |
Teraz a=3 Teraz a=4 Teraz a=5 |
Teraz a=5 | Teraz a=1 Teraz a=2 Teraz a=3 Teraz a=4 |
Teraz a=3 Teraz a=4 |
Teraz a=5 Teraz a=6 |
Zazwyczaj w danym języku programowania zdefiniowane w składni konstrukcje pętli repetycyjnych są tak określone, że jest możliwe sprawdzenie jedynie warunku albo na początku, albo na końcu pętli – nie ma w tym przypadku możliwości zdefiniowania warunków sprawdzanych zarówno na początku, jak i na końcu pętli (np. C[7][8][9][10], C++[9][11], Pascal[1][2]). Inaczej jest jednak, gdy zdefiniowana jest w języku jedna konstrukcja pętli, w której można definiować warunki za pomocą opcjonalnych fraz instrukcji, tak jak zostało to przyjęte np. w języku PL/I[5][6].
PL/I[5][6] | C[7][8][9][10], C++[9][11] |
---|---|
DO WHILE A<B UNTIL C>B;
/* instrukcje pętli */
/* brak konieczności stosowania
instrukcji warunkowej i opuszczenia
wszystkie warunki zdefiniowane w nagłówku
pętli za pomocą odpowiednich fraz */
END;
|
while(a<b)
{
/* instrukcje pętli */
/* sprawdzenie dodatkowego warunku
na końcu pętli wymaga użycia
instrukcji warunkowej i opuszczenia */
if(!(c>b)) break;
}
|
Także rzadko występującą możliwością konstruowania pętli jest możliwość jej kontynuowania po zakończeniu bieżącego warunku, już dla innego, kolejnego warunku.
DO WHILE A<B UNTIL C>B, WHILE D<B, UNTIL D>A;
/* instrukcje pętli */
/* wykonanie pętli nastąpi kolejno dla 3 niezależnych warunków:
– dla A<B (warunek sprawdzany na początku pętli) i równocześnie C>B (ale warunek sprawdzany na końcu pętli),
– a po zakończeniu pętli dla powyższych warunków, dla D<B (warunek sprawdzany na początku pętli),
– i następnie dla D>A (warunek sprawdzany na końcu pętli) */
END;
O sposobie i miejscu zapisu warunków sprawdzających decyduje składnia danego języka programowania. Dla warunków sprawdzanych wewnątrz bloku instrukcji definiujących kolejne iteracje, zapis zawarty jest w ciągu tych instrukcji (np. Ada[12][13], Forth[14][15]). Natomiast dla warunków sprawdzanych na początku i końcu pętli spotyka się rozwiązania, w których albo warunki zapisywane są odpowiednio w miejscu ich wykonywania, tj. na początku i na końcu (np. C[7][8][9][10], C++[9][11], Pascal[1][2], Modula-2[16], Visual Basic[3], VBA[4] i wiele innych), albo rzadziej wszystkie warunki, także te sprawdzane na końcu pętli, definiowane są na początku pętli, w jej nagłówku, w jednym miejscu określającym sposób kolejnych iteracji (np. PL/I[5][6]). W językach programowania, w których nie ma konstrukcji do sprawdzania warunku wewnątrz bloku pętli, dostępne są często instrukcje umożliwiające zmianę przebiegu wykonywania pętli, takie jak instrukcja opuszczenia czy instrukcja kontynuacji (np. C[7][8][9][10], C++[9][11]: break
, continue
), które stosowane w połączeniu z instrukcją warunkową lub wyboru (np. C[7][8][9][10], C++[9][11]: if
, switch
), zapewniają praktycznie równorzędne środki sterowania przebiegiem realizacji algorytmu.
Sposób zapisu | Przykłady | |
---|---|---|
Sprawdzenie warunku wewnątrz pętli | Ada[12][13] | Forth[14][15] |
loop
-- instrukcje przed sprawdzeniem warunku
exit when warunek;
-- instrukcje po sprawdzeniu warunku
end loop;
-- instrukcje za pętlą
|
BEGIN
( instrukcje przed sprawdzeniem warunku )
( warunek ) WHILE
( instrukcje po sprawdzeniu warunku )
REPEAT
( instrukcje za pętlą )
| |
Konstrukcje "zastępcze" | C[7][8][9][10], C++[9][11] | PL/I[5][6] |
wymagane użycie
|
wymagane użycie
| |
while(1)
{
/* instrukcje przed sprawdzeniem warunku */
if(warunek) break;
/* instrukcje po sprawdzeniu warunku */
}
/* instrukcje za pętlą */
|
DO WHILE '1'B;
/* instrukcje przed sprawdzeniem warunku */
IF warunek THEN
GOTO LAB;
/* instrukcje po sprawdzeniu warunku */
END;
LAB: /* instrukcje za pętlą */
|
Typowe konstrukcje składniowe
edytujSkładnia poszczególnych języków programowania definiuje sposób zapisu poszczególnych elementów danego języka i jest różna w zależności od przyjętych przez jego autora rozwiązań. Spotyka się jednak w językach pewną grupę typowych, używanych słów kluczowych, które stanowią podstawę zapisu instrukcji[1][2][7][8][9] lub odpowiednich fraz instrukcji[5][6], definiujących warunki jej wykonania. Są to np.
- while warunek
- to słowo kluczowe stosowane w wielu językach programowania definiuje warunek, który musi być spełniony, aby pętla była wykonywana, stosowana jest zarówno na początku pętli (np. C[7][8][9], C++[9]:
while(warunek) instrukcja
; Pascal:while warunek do instrukcja
), jak i na końcu (np. C[7][8][9], C++[9]:do instrukcje while(warunek);
). - until warunek
- to słowo kluczowe w różnych językach ma różne implikacje:
- warunek który określa, iż pętla będzie powtarzana dopóki warunek nie stanie się spełniony, np. Pascal:
reperat instrukcje until warunek
; Visual Basic[3], VBA[4]:Do Until warunek instrukcje Loop
,Do instrukcje Loop Until warunek
; - warunek, który jest sprawdzany na końcu pętli (choć zapis warunku znajduje się na jej początku w nagłówku definiującym), a pętla jest powtarzana jeżeli warunek jest spełniony, np. PL/I[5][6]:
DO UNTIL warunek; instrukcje END;
(odpowiednik instrukcjido ... while(warunek);
z języka C[7][8][9], C++[9]).
- warunek który określa, iż pętla będzie powtarzana dopóki warunek nie stanie się spełniony, np. Pascal:
Przykłady pętli repetycyjnych
edytujspełnienie/nie spełnienie | język programowania | miejsce sprawdzania warunku | miejsce zapisu warunku sprawdzanego na końcu pętli | |
---|---|---|---|---|
na początku pętli | na końcu pętli | |||
powtórzenie gdy warunek spełniony |
C[7][8][9][10] C++[9][11] |
while(a<MAX_A)
{
printf("a=%d",a++);
}
|
do
printf("a=%d",a++);
while(a<MAX_A);
|
na końcu |
Pascal[1][2] |
while a<MAX_A do
begin
writeln("a=",a);
a:=a+1
end;
|
|||
Modula-2[16] |
WHILE A<MAX_A DO
WRITE("a=",A);
A:=A+1
END;
|
|||
PL/I[5][6] |
DO WHILE A<MAX_A;
CALL WRITE('A=',A);
A=A+1;
END;
|
DO UNTIL A<MAX_A;
CALL WRITE('A=',A);
A=A+1;
END;
|
na początku | |
Visual Basic[3] VBA[4] |
Do While a<MAX_A
Call WriteLine("a=", a)
a=a+1
Loop
|
Do
Call WriteLine("a=", a)
a=a+1
Loop While a<MAX_A
|
na końcu | |
powtórzenie gdy warunek nie spełniony |
Do Until a=MAX_A
Call WriteLine("a=", a)
a=a+1
Loop
|
Do
Call WriteLine("a=", a)
a=a+1
Loop Until a=MAX_A
|
na końcu | |
Pascal[1][2] Modula-2[16] |
repeat
writeln("a=",a);
a:=a+1
until a=MAX_A;
|
na końcu |
Pętla repetycyjna w językach programowania
edytujmiejsce sprawdzania warunku | na początku pętli | wewnątrz pętli | na końcu pętli | |||
---|---|---|---|---|---|---|
język programowania | gdy warunek spełniony | gdy nie spełniony | gdy warunek spełniony | gdy nie spełniony | gdy warunek spełniony | gdy nie spełniony |
Ada[12][13] | [b] | |||||
AWK[17] | ||||||
BCPL[18] | ||||||
C[7][8][9][10] C++[9][11] |
||||||
Clipper[19][20] | ||||||
Comal[21] | ||||||
Eiffel[22] | ||||||
Forth[c][14][15] | [b] | [b] | ||||
MCPL[23] | ||||||
Modula-2[16] | ||||||
Pascal[1][2] | ||||||
Perl[24] | [d] | [d] | ||||
PL/I[5][6] | ||||||
PL/M[25][26] | ||||||
PL/pgSQL[27] | [b] | |||||
Ruby[28] | ||||||
Visual Basic[3] VBA[4] |
Uwagi
edytuj- ↑ Uwzględniono jedynie konstrukcje językowe zdefiniowane dla pętli; nie uwzględniono konstrukcji "zastępczych", tj. wymagających użycia instrukcji warunkowych.
- ↑ a b c d W językach takich jak Ada, Forth, czy PL/pgSQL, warunek sprawdzający wewnątrz pętli może zostać umieszczony na samym początku lub na samym końcu pętli, i wtedy mamy do czynienia z przypadkami krańcowymi, lecz nie są to odrębne konstrukcje składniowe, a jedynie przypadki szczególne sprawdzania warunku wewnątrz pętli, w związku z czym nie zostały one uwzględnione w zestawieniu
- ↑ Uwzględniono standardowo dostępną konstrukcję pętli; język Forth jest językiem rozszerzalnym – można w nim zdefiniować za pomocną odpowiednich kompilatorów (rozumianych w sensie języka Forth) nowe instrukcje sterujące i strukturalne, w tym konstrukcje pętli, które odpowiadałyby pozostałym przypadkom.
- ↑ a b W języku Perl warunki sprawdzane na początku pętli są strukturami sterującymi, warunki sprawdzane na końcu pętli są zrealizowane jako modyfikatory.
Przypisy
edytuj- ↑ a b c d e f g Michał Iglewski, Jan Madey, Stanisław Matwin: Pascal. Język wzorcowy – Pascal 360. Wyd. trzecie – zmienione. Warszawa: Wydawnictwa Naukowo-Techniczne, 1984, seria: Biblioteka Inżynierii Oprogramowania. ISBN 83-85060-53-7. ISSN 0867-6011. (pol.).
- ↑ a b c d e f g h Andrzej Marciniak: Borland Pascal 7.0. Poznań: Nakom, 1994, seria: Biblioteka Użytkownika Mikrokomputerów. ISBN 83-85060-53-7. ISSN 0867-6011. (pol.).
- ↑ a b c d e f Podręcznik Visual Basic na Wikibooks
- ↑ a b c d e f John Walkenbach: Excel 2003 PL. Programowanie w VBA.. HELION, 2004. ISBN 837361-504-0. (pol.).
- ↑ a b c d e f g h i j Jan Bielecki: Rozszerzony PL/I i JCL w systemie OS/RIAD. Warszawa: Państwowe Wydawnictwo Naukowe, 1986, seria: Biblioteka Informatyki. ISBN 83-01-06146-4. (pol.).
- ↑ a b c d e f g h i j M. I. Auguston i inni: Programowanie w języku PL/1 OS JS. Warszawa: Państwowe Wydawnictwo Naukowe, 1988. ISBN 83-01-07463-9. (pol.).
- ↑ a b c d e f g h i j k l m n Brian W. Kernighan, Dennis M. Ritche: Język C. Warszawa: Wydawnictwa Naukowo-Techniczne, 1988, seria: Biblioteka Inżynierii Oprogramowania. ISBN 83-204-1067-3. (pol.).
- ↑ a b c d e f g h i j k l m n Jan Bielecki: Turbo C z grafiką na IBM PC. Warszawa: Wydawnictwa Naukowo-Techniczne, 1990, seria: Mikrokomputery. ISBN 83-204-1101-7. (pol.).
- ↑ a b c d e f g h i j k l m n o p q r s t u v w x y z Jan Bielecki: Od C do C++, programowanie obiektowe w języku C. Warszawa: Wydawnictwa Naukowo-Techniczne, 1990. ISBN 83-204-1332-X. (pol.).
- ↑ a b c d e f g h i j Podręcznik języka C na Wikibooks
- ↑ a b c d e f g h i Podręcznik języka C++ na Wikibooks
- ↑ a b c A. Nico Habermann, Dewayne E. Perry: Ada dla zaawansowanych. Warszawa: Wydawnictwa Naukowo-Techniczne, 1989, seria: Biblioteka Inżynierii Oprogramowania. ISBN 83-204-1058-4. (pol.).
- ↑ a b c Michał Morawski, Antoni M. Zajączkowski: Wstęp do programowania w języku Ada’95. Wyd. drugie. Łódź: 2004. [dostęp 2011-01-29]. (pol.).
- ↑ a b c Jan Bielecki: Język FORTH. Warszawa: Wydawnictwa Naukowo-Techniczne, 1988, seria: Mikrokomputery. ISBN 83-204-0930-6. (pol.).
- ↑ a b c Jan Ruszczyc: Poznajemy FORTH. Warszawa: SOETO, 1987, seria: Informatyka mikrokomputerowa. (pol.).
- ↑ a b c d Niklaus Wirth: Modula 2. Warszawa: Wydawnictwa Naukowo-Techniczne, 1987, seria: Biblioteka Inżynierii Oprogramowania. ISBN 83-204-0828-8. ISSN 0867-6011. (pol.).
- ↑ Tomasz Przechlewski: Opis języka AWK. [dostęp 2011-01-31]. (ang.).
- ↑ Martin Richards: The BCPL Cintsys and Cintpos User Guide. Cambridge: Computer Laboratory University of Cambridge, January 28, 2011. [dostęp 2011-01-31]. (ang.).
- ↑ Wojciech Rogowski, Arkadiusz Serodziński: Clipper 5.0. Warszawa: Wydawnictwo PLJ, 1991. ISBN 83-85190-20-1. (pol.).
- ↑ Krzysztof Walczak: Język Clipper. Warszawa: Wydawnictwa Naukowo-Techniczne, 1990, 1991, seria: Podręczna Pamięć Programisty. ISBN 83-204-1359-11. (pol.).
- ↑ Mike Ducka, tłumaczenie: Marcin Turski: Języki mikrokomputerów. Przewodnik dla początkujących. Basic, Pascal, Logo, Prolog, Comal, Forth. Warszawa: Wydawnictwa Naukowo-Techniczne, 1988. ISBN 83-204-0966-7. (pol.).
- ↑ Bertrand Meyer: Eiffel*: A Language and Environment for Software Engineering. Goleta, California: Interactive Software Engineering Inc.. [dostęp 2011-01-31]. (ang.).
- ↑ Martin Richards: The MCPL Programming Manual and User Guide. Cambridge: Computer Laboratory University of Cambridge, May 23, 2007. [dostęp 2011-01-31]. (ang.).
- ↑ Podręcznik języka Perl na Wikibooks
- ↑ Jan Bielecki: PL/M język programowania mikroprocesorów. Wyd. drugie uzupełnione. Warszawa: Wydawnictwa Komunikacji i Łączności, 1987, seria: Elektronizacja. zeszyt 25. (pol.).
- ↑ Jan Bielecki: System operacyjny ISIS-II. Warszawa: Wydawnictwa Naukowo-Techniczne, 1987, seria: Mikrokomputery. ISBN 83-204-0893-8. (pol.).
- ↑ PostgreSQL 8.3.13 Documentation. [dostęp 2011-01-31]. (ang.).
- ↑ Podręcznik języka Ruby na Wikibooks
Bibliografia
edytuj- Michael Marcotty, Henry Ledgord, tłumaczenie: Krystyna Jerzykiewicz: W kręgu języków programowania. Warszawa: Wydawnictwa Naukowo-Techniczne, 1980, seria: Biblioteka Inżynierii Oprogramowania. ISBN 83-204-1342-7. (pol.).
- John E. Nicholls: Struktura języków programowania. Warszawa: Wydawnictwa Naukowo-Techniczne, 1980, seria: Informatyka. ISBN 83-204-0246-8. (pol.).
- Mike Ducka, tłumaczenie: Marcin Turski: Języki mikrokomputerów. Przewodnik dla początkująych. Basic, Pascal, Logo, Prolog, Comal, Forth. Warszawa: Wydawnictwa Naukowo-Techniczne, 1988. ISBN 83-204-0966-7. (pol.).