• Nie Znaleziono Wyników

Dr inż. Robert Wójcik

N/A
N/A
Protected

Academic year: 2021

Share "Dr inż. Robert Wójcik"

Copied!
1
0
0

Pełen tekst

(1)

Dr inż. Robert Wójcik

E-mail: wojcik@ict.pwr.wroc.pl

Języki i metody programowania

5. Instrukcje iteracyjne 5.1. Pętla for ... to („dla”)

5.2. Pętla for ... downto („dla”) 5.3. Pętla while („dopóki”)

5.4. Pętla repeat („wykonuj aż do”) 5.5. Pętle zagnieżdżone

5.6. Instrukcje sterujące przebiegiem programu

 break

 continue.

5. Instrukcje iteracyjne

(2)

Iteracja – cykliczne wykonywanie sekwencji rozkazów.

Aby zaprojektować iterację należy określić:

 ciąg instrukcji, które mają być powtarzane,

 warunek kontynuowania lub zakończenia tego ciągu.

Pętle są istotne dla wykonywania cyklicznych zadań takich jak powtarzanie sekwencji instrukcji lub dostęp do elementów tablicy.

W ogólnym przypadku można wyróżnić trzy rodzaje pętli:

 o ustalonej ilości przebiegów – powtarzają pewne instrukcje określoną liczbę razy;

 warunkowe – powtarzają pewne instrukcje dopóki sprawdzany warunek jest prawdziwy lub dopóki sprawdzany warunek jest fałszywy;

 nieskończone – pętle otwarte, powtarzają pewne instrukcje

w nieskończoność (posiadają mechanizm opuszczenia pętli).

5.1. Pętla for ... to

Instrukcja for ... to tworzy pętlę, w której grupa instrukcji jest powtarzana określoną liczbę razy.

for zm_ster:=wyr1 to wyr2 do begin

instr_1;

instr_2;

...

instr_k; { sekwencja instrukcji } end;

zm_ster – zmienna sterująca pętli; zmienna dowolnego typu porządkowego, np. integer, longint, char;

(3)

wyr1, wyr2 - wyrażenia zgodne z typem zmiennej sterującej zm_ster;

wyr1 – wyrażenie określające wartość początkową zm_ster;

wyr2 – wyrażenie określające wartość końcową zm_ster.

W szczególności można powtarzać tylko jedną instrukcję.

for zm_ster:=wyr1 to wyr2 do instrukcja;

Przykłady prostych pętli.

Var i: integer;

z: char;

for i:=1 to 10 do { i – zmienna sterująca; wyr1=1; wyr2=10 } begin

writeln(i); { wydruk liczb od 1 do 10 } readln; { oczekiwanie na enter } end;

for i:=1 to 5 do writeln(i); { wydruk liczb od 1 do 5 }

for z:=’a’ to ’h’ do writeln(z); { wydruk znaków od a do h } Algorytm działania pętli for ... to

W pętli tej instrukcje instr_1 do instr_k są powtarzane dla kolejnych wartości zmiennej sterującej począwszy od wartości wyr1 do wartości wyr2.

Wartości wyrażeń wyr1 i wyr2 są obliczane jeden raz, przed rozpoczęciem wykonywania pętli. Jeśli wyr1 > wyr2, to instrukcje wewnętrzne pętli nie będą wykonane ani razu. Jeśli wyr1 <= wyr2, to realizowane są wewnętrzne instrukcje pętli. W każdym kroku wartość zmiennej sterującej jest modyfiko- wana automatycznie zgodnie z zależnością:

zm_ster:= SUCC(zm_ster);

gdzie funkcja SUCC(x) wyznacza następnika wartości x w ramach typu porządkowego. W przypadku, gdy x jest liczbą całkowitą instrukcja SUCC(x) jest równoważna ze zwiększeniem wartości x o jeden, tj. x: = x + 1.

Po każdej iteracji, po napotkaniu dyrektywy end w pętli lub po napotkaniu średnika, następuje sprawdzenie warunku końca pętli w postaci:

if (zm_ster = wyr2) then koniec_pętli else zm_ster:=SUCC(zm_ster);

Pętla jest powtarzana dopóki wartość zmiennej sterującej zm_ster <= wyr2.

(4)

Jeśli na końcu pętli zachodzi zm_ster = wyr2, to następuje koniec pętli.

W zakresie pętli nie zaleca się modyfikowania zmiennej sterującej. Jeśli się to zrobi, to należy uwzględnić, że wartość zmiennej zostanie dodatkowo zmieniona w ramach pętli.

Przykłady pętli rozbudowanych.

Var i, k: integer;

k:=0;

for i:= 1 to 10 do { zliczanie ilości liczb parzystych } if (i mod 2 = 0) then begin writeln(i); inc(k); end;

Var x, s : real;

i, w : longint;

w:=1; { obliczenie iloczynu: 1 x 2 x ... x 10 = 10! } for i:=1 to 10 do w:= w  i;

s:=0; { obliczenie sumy: 1 + 2 + ... + 10 } for i:=1 to 10 do s:= s + i;

s:=0; x:=0.1; { obliczenie sumy: 0.1 + 0.2 + ... + 1.0 } for i:=1 to 10 do

begin

s:= s + x  i; writeln(s);

end;

Pętla pusta

Pętla for może być pusta (kończy się średnikiem). Wykonanie takiej pętli prowadzi jedynie do modyfikacji zmiennej sterującej.

for i:=5 to 10 do ; { pusta pętla for }

Po osiągnięciu przez i wartości 10 następuje koniec pętli.

Przykład 5.1. Obliczanie n! . Var i,n : integer;

silnia: real;

begin

clrscr; silnia:=1;

writeln(’Podaj n z zakresu [1..20]:’);

readln(n);

(5)

if (n >0) and (n <=20) then begin

for i:=1 to n do silnia:=silnia*i;

writeln(n,’!= ’, silnia);

end else

writeln(’Liczba n jest spoza zakresu ’);

readln;

end.

Przykład 5.2. Wyprowadzanie liczb na ekran wierszami.

Var a, i, j :integer;

begin

clrscr; randomize;

{ wyprowadzanie wierszami – 4 wiersze po 8 liczb w wierszu } for i:=1 to 32 do

begin

a:= random(100);

if (i mod 8 > 0) then write(a : 3) else writeln(a : 3);

end;

end.

5.2. Pętla for ... downto

Instrukcja for ... downto tworzy pętlę, w której grupa instrukcji jest powtarzana określoną liczbę razy – podobnie jak w przypadku instrukcji for ... to.

W rozpatrywanej pętli zmienna sterująca zmienia się jednak w inny sposób, tj.

począwszy od większych wartości porządkowych do mniejszych.

for zm_ster:=wyr1 downto wyr2 do begin

instr_1;

instr_2;

...

(6)

instr_k; { sekwencja instrukcji } end;

zm_ster – zmienna sterująca pętli; zmienna dowolnego typu porządkowego, np. integer, longint, char;

wyr1, wyr2 - wyrażenia zgodne z typem zmiennej sterującej zm_ster;

wyr1 – wyrażenie określające wartość początkową zm_ster;

wyr2 – wyrażenie określające wartość końcową zm_ster.

W szczególności można powtarzać tylko jedną instrukcję.

for zm_ster:=wyr1 downto wyr2 do instrukcja;

Przykłady prostych pętli.

Var i: integer;

z: char;

for i:=10 downto 1 do { i – zmienna sterująca; wyr1=10; wyr2=1 } begin

writeln(i); { wydruk liczb od 10 do 1 } readln; { oczekiwanie na enter } end;

for i:=5 downto 1 do writeln(i); { wydruk liczb od 5 do 1 }

for z:=’h’ downto ’a’ do writeln(z); { wydruk znaków od h do a }

Algorytm działania pętli for ... downto

W pętli tej instrukcje instr_1 do instr_k są powtarzane dla kolejnych wartości zmiennej sterującej począwszy od wartości wyr1 do wartości wyr2.

Wartości wyrażeń wyr1 i wyr2 są obliczane jeden raz, przed rozpoczęciem wykonywania pętli. Jeśli wyr1 < wyr2, to instrukcje wewnętrzne pętli nie będą wykonane ani razu. Jeśli wyr1 >= wyr2, to realizowane są wewnętrzne instrukcje pętli. W każdym kroku wartość zmiennej sterującej jest modyfiko- wana automatycznie zgodnie z zależnością:

zm_ster:= PRED(zm_ster);

(7)

gdzie funkcja PRED(x) wyznacza poprzednika wartości x w ramach typu porządkowego. W przypadku, gdy x jest liczbą całkowitą instrukcja PRED(x) jest równoważna ze zmniejszeniem wartości x o jeden, tj. x: = x - 1.

Po każdej iteracji, po napotkaniu dyrektywy end w pętli lub po napotkaniu średnika, następuje sprawdzenie warunku końca pętli w postaci:

if (zm_ster = wyr2) then koniec_pętli else zm_ster:=PRED(zm_ster);

Pętla jest powtarzana dopóki wartość zmiennej sterującej zm_ster >= wyr2.

Jeśli na końcu pętli zachodzi zm_ster = wyr2, to następuje koniec pętli.

W zakresie pętli nie zaleca się modyfikowania zmiennej sterującej. Jeśli się to zrobi, to należy uwzględnić, że wartość zmiennej zostanie dodatkowo zmieniona w ramach pętli.

Przykłady pętli rozbudowanych.

Var s : real;

i, w : longint;

w:=1; { obliczenie iloczynu: 10 x 9 x ... x 1 = 10! } for i:=10 downto 1 do w:= w  i;

s:=0; { obliczenie sumy: 10 + 9 + ... + 1 } for i:=10 downto 1 do s:= s + i;

5.3. Pętla while („dopóki”)

Pętla warunkowa while ma następującą składnię:

while (wyr) do begin

{ <sekwencja instrukcji>; } end;

while (wyr) do instrukcja;

Wyrażenie warunkowe wyr jest dowolnym wyrażeniem zgodnym z typem boolean. Jest ono obliczane przed wykonaniem instrukcji pętli. Jeśli wyrażenie jest fałszywe, to instrukcje pętli while nie zostaną wykonane. Zmienne sterujące pętlą muszą być modyfikowane przez programistę.

(8)

Var zn: char;

i: integer;

s: real;

zn:=’x’;

while (zn <> ’k’) do zn:= readkey; { oczekiwanie na ’k’ } i:=0; { wyprowadzanie liczb od 0 do 9 }

while (i < 10) do begin

writeln(i);

inc(i); { i:= i+1 } end;

i:=0; { wyprowadzanie 0, 3, 6, 9 } while (i < 10) do

begin

writeln(i);

i:= i+3; { przyrost i o 3 } end;

i:=9; { wyprowadzanie liczb od 9 do 0 } while (i >= 0) do

begin writeln(i);

dec(i); { i:= i -1 } end;

s:=0; i:=1; { obliczanie sumy: 1 + 2 + ... + 10 } while (i<=10) do

begin s:= s + i;

i:= i+1;

end;

Przykład 5.3. Wprowadzanie znaków i liczb w pętli Var zn: char

koniec: integer;

x: real;

ww: boolean;

begin { wprowadzanie znaków w pętli } koniec:=0;

clrscr;

while koniec<>1 do begin

(9)

writeln(’Wpisz znak (N - koniec) : ’);

readln(zn);

if (zn = 'n') or (zn = 'N') koniec = 1 else writeln(zn);

end;

x:=0; { oczekiwanie na liczbę z przedziału [5, 20] } while (x<5.0) or (x>20.0) do

begin

writeln(’Podaj liczbe z przedzialu [5,20]: ’);

readln(x);

end;

ww:= false; { oczekiwanie na liczbę z przedziału [5, 20] } while not (ww) do

begin

readln(x);

ww:= (x>=5.0) and (x<=20.0); { znaleziono – ww:=true } end;

readln;

end.

5.4. Pętla repeat („wykonuj aż do”)

Pętla warunkowa repeat ma następującą składnię:

repeat

{ <sekwencja instrukcji>; } until (wyr);

repeat instrukcja; until(wyr);

Wyrażenie warunkowe wyr jest dowolnym wyrażeniem zgodnym z typem boolean. Jest ono obliczane na końcu instrukcji pętli. Jeśli wyrażenie jest prawdziwe, to instrukcje pętli repeat nie zostaną wykonane.

Var zn: char;

i: integer;

s: real;

zn:=’x’;

repeat zn:= readkey; until (zn=’k’); { oczekiwanie na ’k’ } i:=0; { wyprowadzanie liczb od 0 do 9 }

(10)

repeat writeln(i);

inc(i); { i:= i+1 } until (i>=10);

i:=0; { wyprowadzanie 0, 3, 6, 9 } repeat

writeln(i);

i:= i+3; { przyrost i o 3 } until (i>=10);

i:=9;

repeat { wyprowadzanie liczb od 9 do 0 } writeln(i);

dec(i); { i:= i -1 } until (i<0);

s:=0; i:=1; { obliczanie sumy: 1 + 2 + ... + 10 } repeat

s:= s + i; i:= i+1;

until (i>10);

5.5. Pętle zagnieżdżone

Pętle mogą być wielokrotnie zagnieżdżane.

Przykład 5.4. Wyprowadzanie liczb na ekran wierszami.

Var a, i, j :integer;

begin { wyprowadzanie wierszami – 4 wiersze po 8 liczb w wierszu; 2 pętle } clrscr; randomize;

for i:=1 to 4 do begin

for j:=1 to 8 do begin

a:= random(100); write(a: 3);

end;

writeln;

end;

readln;

end.

Przykład 5.5. Wyprowadzanie figur o wysokości i podstawie h.

X X h XX XX h

(11)

XXX XXX Var

i,j, x,y, h :integer;

begin

clrscr; x:=1; y:=1; h:=7;

for i:=1 to h do begin

gotoxy(x, y+i);

for j:=1 to i do write('X');

end;

x:=20; y:=1;

for i:=1 to h do begin

gotoxy(x-i, y+i);

for j:=1 to i do write('X');

end;

readln;

end.

Można również zrealizować poprzedni przykład bez korzystania z procedury gotoxy. W tym celu dla pierwszego trójkąta drukujemy w jednym wierszu i znaków ’X’ oraz (h-i) spacji. Dla drugiego trójkąta drukujemy najpierw (h-i) spacji, a następnie i znaków ’X’.

uses crt;

var i, j, x, y, h: integer;

begin clrscr;

x:=1; y:=1; h:=7;

for i:=1 to h do begin

for j:=1 to i do write('X');

for j:=1 to h-i do write(' ');

writeln;

end;

readln;

x:=20; y:=1; h:=7;

for i:=1 to h do begin

for j:=1 to h-i do write(' ');

for j:=1 to i do write('X');

writeln;

(12)

end;

readln;

end.

5.6. Instrukcje sterujące przebiegiem programu Procedura Break

Procedura Break umożliwia przerwanie procesu iteracji. Wywołanie Break powoduje zakończenie pętli i przejście do wykonania kolejnych instrukcji.

Procedura może być stosowana dla każdej ze znanych rodzajów iteracji (for, repeat, while).

while wyr do begin

instr1;

instr2;

if wyr_1 then Break; { skok za end do nast_instrukcje } instr3;

...

instrN;

end;

nast_instrukcje;

W przypadku, gdy wyr_1 jest prawdziwe pętla jest przerywana. Realizowane są operacje określone przez nast_instrukcje.

Przykład 5.6. Poszukiwanie losowej liczby całkowitej należącej do przedziału [40, 50]. Liczby są losowane z przedziału [0,100].

Procedure Wypisz;

(13)

Var i: word;

Begin i:=0;

{ inicjacja generatora w programie głównym - randomize } while true do { pętla nieskończona }

begin

i:= random(101);

writeln(i);

if (i >=40) and (i<=50) then Break;

end.

End;

Procedura Continue

Procedura Continue umożliwia pominięcie instrukcji wykonywanych w pętli.

Pomijane są wszystkie instrukcje występujące w pętli po instrukcji Continue.

Procedura może być stosowana dla każdej ze znanych rodzajów iteracji (for, repeat, while). W przypadku pętli for automatycznie przyjmowana jest następna wartość licznika pętli.

while wyr do begin

instr1;

instr2;

if wyr_1 then Continue; { skok na początek pętli - while } instr3;

...

instrN;

end;

W przypadku, gdy wyr_1 jest prawdziwe instrukcje instr3 do instrN są pomi- jane. Rozpoczyna się kolejna iteracja pętli.

Przykład 5.7. Wyprowadzanie na ekran losowych liczb nieparzystych należących do przedziału [0, 100]. Liczba prób 70.

Procedure Wypisz;

Var i, n: word;

Begin

i:=1; n:=1;

(14)

{ inicjacja generatora w programie głównym - randomize } while n<=70 do { liczba prób }

begin inc(n);

i:= random(101);

if (i mod 2 = 0) then Continue; { liczba parzysta – nie pisz } writeln(i); { pisz liczbę nieparzystą }

end;

End;

Cytaty

Powiązane dokumenty

Badania przeprowadzone były dla jednofazowego przepływu gazu przez złoże jednego z trzech rodzajów pian metalicznych (aluminiowej, chromoniklowej i niklowej) o

Osoby, które otrzymały z laboratorium 3.5 mogą pomylić się tylko raz natomiast osoby, które otrzymały tylko 3.0 muszą odpowiedzieć prawidłowo na oba pytania.. W przypadku

Kod źródłowy programu - zakodowana postać algorytmów stanowiących rozwiązanie problemu; tworzony pod dowolnym edytorem; jest najczęściej zapisywany za pomocą

Liczba elementów rozszerzonych ciał skończonych jest równa potędze liczby pierwszej p, gdzie p jest liczbą elementów ciała prostego, jeśli tworzymy rozszerzenie

W przypadku, gdy liczba błędów lub ich rozkład w wektorze odebranym przekracza możliwości korekcyjne kodu, dekoder, analizując ciąg odebrany, może znaleźć

Obliczenia można wykonywać stosując zasady arytmetyki (redukcji) modularnej lub stosując poniższy algorytm numeryczny. Funkcje szyfrująca i deszyfrująca są wzajemnie odwrotne, co

W tym przypadku klucz publiczny serwera WWW, uzyskany z jego certyfikatu, jest wykorzystywany do szyfrowania danych przesyłanych do serwera przez przeglądarkę

Dzięki temu może przechwytywać wiadomości przesyłane od A do B, modyfikować je, a następnie odsyłać do B.. Są udoskonalenia protokołu Diffie-Hellman, które uodparniają go na