PP W8, Podstawy programowania


8. INSTRUKCJE POWTARZAJĄCE

8.1. Instrukcja while-do

Instrukcje powtarzające znajdują zastosowanie, gdy działanie programu opiera się na algorytmie iteracyjnym, w którym trzeba wielokrotnie powtarzać jakąś instrukcję lub sekwencję instrukcji.

Jedną z trzech instrukcji powtarzających Turbo Pascala jest instrukcja while-do (po polsku: dopóki-wykonuj) :

while wyr_rel do begin

instrukcja_1;

instrukcja_2;

{---------}

instrukcja_N;

end;

.Dopóki wyrażenie relacyjne po słowie while jet prawdziwe (ma wartość True), wewnętrzny ciąg instrukcji jest cyklicznie powtarzany. Kolejny cykl nie zostanie wykonany i instrukcja zakończy działanie, gdy wyrażenie po while przestanie być prawdziwe (przyjmie wartość False).

0x08 graphic

Uwaga: Prawdziwość wyrażenia po while warunkiem rozpoczęcia kolejnego cyklu. W przypadku, gdy w chwili rozpoczęcia działania instrukcji wyrażenie po while nie jest prawdziwe, wewnętrzna sekwencja instrukcji nie wykona się w ogóle!

Przykład: Przekształcenie liczby dziesiętnej na jej zapis dwójkowy.

Algorytm: Metoda polega na wielokrotnym dzieleniu całkowitym danej liczby dziesiętnej, a następnie kolejno otrzymywanych ilorazów, przez 2. Otrzymywane wartości reszty (1 lub 0) są kolejnymi pozycjami poszukiwanego zapisu dwójkowego, w porządku od najmłodszej do najstarszej pozycji. Proces kończy się, gdy kolejny iloraz jest zerowy:

Na przykład przekształcenie liczby 12 przebiega, jak następuje:

Krok 1: 12 mod 2 = 0, 12 div 2 = 6

Krok 2: 6 mod 2 = 0, 6 div 2 = 3

Krok 3: 3 mod 2 = 1, 3 div 2 = 1

Krok 4: 1 mod 2 = 1, 1 div 2 = 0

W wyniku otrzymujemy: 1 1 0 0

Odpowiedni program z zastosowaniem instrukcji while-do pokazano poniżej ('#8' jest znakiem cofnięcia kursora).

program Dec_bin;

{Przekształca liczbę dziesiętną na dwójkową.}

uses Crt;

var D,R:Word;

begin

Clrscr;

Write('Jaka liczba dziesietna? ');

Readln(D);

Write('Binarny zapis liczby: ');

GotoXY(Wherex+16,Wherey);

while D<>0 do begin

R:=D mod 2;

D:=D div 2;

Write(R,#8#8); {pisanie reszt wspak}

end;

Readln;

end.

8.2. Instrukcja powtarzająca repeat-until

Zapis instrukcji repeat-until (po polsku: powtarzaj-aż) wygląda, jak następuje:

repeat

instrukcja_1;

instrukcja_2;

{----}

instrukcja_N;

until wyrażenie_relacyjne;

0x08 graphic
Działanie omawianej instrukcji pokazuje graf na rysunku:

Uwaga: Prawdziwość warunku po until jest warunkiem zakończenia instrukcji.

Przykład: Generacja 6 liczb losowych z przedziału 1..49 za pomocą funkcji Random.

program Totek;

uses Crt;

var R,J : Byte;

begin

Clrscr;

J:=0;

Randomize;

repeat

R:=1+Random(49);

Write(R:3);

J:=J+1;

until J=6;

Readln;

end.

Poniżej pokazano wersję programu, która uniemożliwia wystąpienie w serii 6 wylosowanych liczb losowych dwóch lub więcej takich samych wartości.

program Totek_1;

uses Crt;

var R,R1,R2,R3,R4,R5,R6,J:Byte;

begin

Clrscr;

J:=1;

R1:=0; R2:=0; R3:=0; R4:=0; R5:=0; Randomize;

repeat

R:=1+Random(49);

if(R=R1)or(R=R2)or(R=R3)or(R=R4)or(R=R5)

then Continue;

if J=1 then R1:=R;

if J=2 then R2:=R;

if J=3 then R3:=R;

if J=4 then R4:=R;

if J=5 then R5:=R;

if J=6 then R6:=R;

J:=J+1;

until J>6;

Write(R1:3,R2:3,R3:3,R4:3,R5:3,R6:3);

Readln;

end.

Przykład: Program obliczający potęgę

przy całkowitych wartościach wykładnika

program Power;

uses Crt;

var X,Wynik:Real;

Wykl,J:Integer;

begin

Clrscr;

Write('Podaj podstawe: ');

Readln(X);

Write('Podaj calkowity wykladnik: ');

Readln(Wykl);

Wynik:=1;

if Wykl<>0 then begin

J:=0;

repeat

J:=J+1;

Wynik:=Wynik*X;

until J=Abs(Wykl);

end;

if Wykl<0 then Wynik:=1.0/Wynik;

Write('Wynik: ',Wynik:0:6);

Readln;

end.

8.3. Instrukcja powtarzająca for-to-do

Ogólny zapis tej instrukcji jest następujący:

for J:=w1 to w2 do begin

instrukcja_1;

instrukcja_2;

{----}

instrukcja_N;

end;

Instrukcja for jest szczególnie przydatna w sytuacji, gdy wymagana liczba powtórzeń jest określona. Wynika to z faktu, że instrukcja for posiada wewnętrzny mechanizm liczenia cykli pracy Tak zwana zmienna sterująca (nazwana tutaj J), służy jako licznik powtórzeń.

Działanie instrukcji for

0x08 graphic

Przykład: Program obliczający wartość funkcji silnia.

program Silnia;

uses Crt;

var Arg,J:Byte;

S:Longint;

begin

Clrscr;

Write('Podaj argument silni <13: ');

Readln(Arg);

if Arg>12 then S:=0

else begin

S:=1;

for J:=1 to Arg do S:=S*J;

end;

if S=0 then Write('Argument za duzy!')

else

Write('Silnia liczby ',Arg,' wynosi ',S);

Readln;

end.

8.4. Instrukcje break i continue

Tych dwóch instrukcji można używać wyłącznie wewnątrz instrukcji powtarzających, gdzie wykonywane są warunkowo, jako składowe instrukcji if-then lub if-then-else.

Rysunek poniżej wyjaśnia działanie instrukcji break (po polsku: przerwij).. Instrukcja ta powoduje natychmiastowe przerwanie działania i zakończenie instrukcji powtarzającej, wewnątrz której została uruchomiona.

Działanie instrukcji break

0x08 graphic

Działanie instrukcji continue

0x08 graphic

Przykład

Program piszący odwrotności liczb losowych

program Ex8_5;

{Wyprowadza na ekran 20 odwrotności liczb losowych z zakresu 0..99.}

uses Crt;

var R:Word;

X:Real;

begin

Clrscr;

J:=0;

repeat

R:=Random(100);

if R=0 then continue;

X:=1.0/R;

Writeln(X:8:6);

J:=J+1;

until J=20;

end.

8.5. Obliczanie wartości funkcji metodą iteracyjną Newtona.

Isaac Newton (1642-1727) wymyślił iteracyjny sposób obliczania wartości funkcji. W zastosowaniu do pierwiastka kwadratowego z liczby A jego metoda prowadzi do uzyskania wzoru:

Xj=(Xj-1*Xj-1+A)/(2*Xj-1);

gdzie Xj jest j-tym przybliżeniem wyniku, a Xj-1 poprzednim przybliżeniem wyniku.

Dzięki własnościom operatora przypisania wzór ten w Turbo Pascalu przybiera postać następującej instrukcji:

X:=(X*X+A)/(2*X);

Przykład

Obliczanie pierwiastka kwadratowego metodą Newtona

program Ex8_6;

{Oblicza pierwiastek kwadratowy z A metodą Newtona.}

uses Crt;

const Eps=1E-7;

var A,X,Xp:Real;

begin

Clrscr;

Write('Podaj argument pierwiastka: ');

Readln(A);

if A<0 then X:=-1 else {przypadki szczególne}

if A=0 then X:=0

else begin

Writeln(#10,'Kolejne aproksymacje:',#10);

X:=A/2; {pierwsze przybliżenie}

Writeln(X:20:9);

repeat {obliczenia iteracyjne}

Xp:=X; {zapamiętanie poprzedniego X}

X:=(X*X+A)/(2*X); {wzór Newtona}

Writeln(X:20:9); {druk wyników pośrednich}

until Abs(X-Xp)<Eps;{warunek zakończenia}

end;

if X=-1 then Write('Argument ujemny !?')

else Write('Wynik: ',X:20:9);

Readln;

end.

Poniżej pokazano postać wydruku wyników, otrzymaną dla argumentu A=2.

Podaj argument pierwiastka: 2

Kolejne aproksymacje:

1.000000000

1.500000000

1.416666667

1.414115686

1.414213562

1.414213562

8.6. Wyznaczanie wartości funkcji sinus metodą sumowania wyrazów szeregu

Funkcję sin(x) można rozwinąć w szereg:

sin(x)=x-x3/3!+x5/5!-x7/7!+ ...

gdzie argument x jest wartością kąta w radianach.

Przekształcić powyższe wyrażenie, by uniknąć odrębnego obliczania wartości każdego kolejnego wyrazu szeregu jako ilorazu xk/k! .

Wprowadzamy pomocniczą zmienną całkowitą k. Na początku k=1, a przy obliczaniu kolejnych wyrazów k przyjmuje wartości nieparzyste:

k = 1, 3, 5, 7 ...

Przy tych założeniach, każdy kolejny wyraz wi+1 (z wyjątkiem pierwszego równego x), można wyznaczyć z poprzedniego wi, jako:

wi+1=(-x2/k(k-1))wi

co w Pascalu przyjmie postać instrukcji:

W:=-W*(X*X)/(K*(K-1));

Przykład

Program obliczający wartość funkcji sinus

program Ex8_7;

{Oblicza sinus metodą sumy szeregu.}

uses Crt;

const Eps=1E-9; {założona dokładność}

var X,W,S:Real;

K:Word;

begin

Clrscr;

Write('Podaj kat w radianach: ');

Readln(X); {odczyt argumentu}

if X>2*Pi then repeat

{normalizacja kąta dla X>0)

X:=X-2*Pi;

until X<2*Pi;

if X<-2*Pi then repeat

{normalizacja kąta dla X<0)

X:=X+2*Pi;

until X>=0;

K:=1; W:=X; S:=X; {wartości początkowe}

while Abs(W)>=Eps do begin

K:=K+2; {nowa wartość K}

W:=-W*X*X/(K*(K-1)) {kolejny wyraz}

S:=S+W{dodanie wyrazu do sumy}

end;

Writeln('Wynik:' ,S:0:9);

Readln;

end.

53

wyrażenie

relacyjne

FALSE

instrukcja_1

instrukcja_2

. . .

instrukcja_n

.

end

begin

TRUE

POCZĄTEK

KONIEC

wyrażenie

relacyjne

FALSE

instrukcja_1

instrukcja_2

. . .

instrukcja_n

.

until

repeat

TRUE

POCZĄTEK

KONIEC

J < = w2

TRUE

instrukcja_1

instrukcja_2

. . .

instrukcja_n

.

FALSE

POCZĄTEK

KONIEC

J: = w1

J: = J + 1

w1 > w2

TRUE

FALSE

wyrażenie

relacyjne

FALSE

instrukcja_1;

instrukcja_2;

. . .

if (war) then break;

instrukcja_k;

. . .

instrukcja_n;

.

end

begin

TRUE

POCZĄTEK

KONIEC

wyrażenie

relacyjne

FALSE

instrukcja_1;

instrukcja_2;

if (war) then

continue;

instrukcja_k;

instrukcja_n;

.

end

begin

TRUE

POCZĄTEK

KONIEC



Wyszukiwarka

Podobne podstrony:
PP temat6, Podstawy programowania
PP 11, Podstawy programowania
PP W7, Podstawy programowania
PP W6, Podstawy programowania
PP temat3, Podstawy programowania
PP W1, Podstawy programowania
PP W4, Podstawy programowania
PP 10, Podstawy programowania
PP W5, Podstawy programowania
PP temat2, Podstawy programowania
PP W9, Podstawy programowania
PP temat4, Podstawy programowania
PP temat5, Podstawy programowania
PP W2, Podstawy programowania
PP W10, Podstawy programowania
PP temat6, Podstawy programowania
zasady zaliczeń PP IG, Politechnika Białostocka, ZiIP (PB), Semestr 1, Podstawy programowania, Progr
pp projekty2004, wisisz, wydzial informatyki, studia zaoczne inzynierskie, podstawy programowania

więcej podobnych podstron