KURS PASCAL A 1.Wprowadzenie Pascal jest językiem wyŝszego poziomu, posiada gotowe biblioteki i moduły, co ułatwia programowanie. Z drugiej strony jest on bardziej wymagający pod względem estetyki programowania np. kaŝda linia musi być zakończona średnikiem ( ; ). 2.Podstawy i składnia Ogólny szkic programu wygląda następująco: deklaracja program nazwa; potem ewentualne dołączanie bibliotek uses nazwa; następnie deklaracje zmiennych i pod spodem np. a:integer; ustalenie zmiennej a jaku typu dziesiętnego, dalej piszesz program i kończysz end. program nazwa; (deklaracja nazwy programu i jego początku) uses nazwa, nazwa2; (dołączanie modułów) const (deklaracje stałych)... (deklaracje zmiennych)... (początek programu, procedury lub funkcji)... end. (koniec programu) 3. Instrukcja warunkowa Do tej pory pisaliśmy jedynie programy wykonujące wszystkie instrukcje kolejno jedna po drugiej. Taka liniowa konstrukcja programu zdarza się dosc rzadko w większości przypadków działanie programu rozgałęzia się w zaleŝności od konkretnych warunków. jeŝeli warunek jest spełniony, to wykonaj jakąś operację w przeciwnym razie wykonaj inną operację Przekładając to na angielski, uzyskujemy dosłowny zapis instrukcji warunkowej w Pascalu: 1
if warunek then { blok instrukcji 1 } else { blok instrukcji 2 } W skróconej wersji moŝna pominąc alternatywną galąź,,w przeciwnym razie", uzyskując cos takiego: if warunek then { blok instrukcji 1 } If... then jezeli... to. Else w przeciwnym razie. PowyŜsza konstrukcja rozpoczyna działanie od sprawdzenia wartości warunku, który musi byc wyraŝeniem logicznym (tj. dawac w efekcie wartosc True lub false). Jeśli warunek jest prawdziwy, wykonywany jest blok instrukcji 1, a jeŝeli nie blok instrukcji 2 (w przypadku formy uproszczonej, jeŝeli warunek jest spełniony, wykonywany jest blok instrukcji 1, a jeŝeli nie, program przechodzi do kolejnych instrukcji programu). Przed słowem else nie moŝe byc średnika! Zwrocmy uwagę na pojęcie blok instrukcji. W programach czesto zdarza się, Ŝe określoną grupę instrukcji trzeba wykonac jako całośc. Do zaznaczenia ich odrębnosci słuŝą znane nam juŝ słowa kluczowe i end, oznaczające oczywiście początek i koniec bloku: instrukcja1; instrukcja2; instrukcjan: ZauwaŜmy, Ŝe po słowie end na końcu bloku znajduje się średnik, a nie kropka, jak ma to miejsce na końcu programu. ZałóŜmy, ze chcemy sprawdzic, czy wartośc zmiennej X jest dodatnia i wypisac odpowiedni komunikat. if X > 0 then { jezeli X jest większe od zera. to... } 2
writeln( X jest dodatnie ); else { w przeciwnym razie... } writeln( X jest ujemne lub równe 0'); PowyŜsza konstrukcja pozwala nam jedynie rozróŝniac pomiędzy liczbami dodatnimi a niedodatnimi. Gdybyśmy chcieli obsłuŝyc trzy przypadki liczby dodatnie, ujemne i zero naleŝałoby uŝyc,,piętrowej" konstrukcji pokazanej poniŝej: if X > 0 then { jezeli X jest wieksze od zera, to... } writeln( X jest wieksze od 0') else { jezeli zaś nie jest. to... } if X < 0 then { jezeli jest mniejsze od zera... } writeln(x jest mniejsze od 0') else { w przeciwnym razie musi bye zerem } writeln( 'X jest rowne 0'); 4. Pętla for for zmienna := początek to koniec do { blok instrukcji } for zmienna := początek downto koniec do { blok instrukcji } PowyŜszy zapis oznacza, Ŝe blok instrukcji będzie wykonywany wielokrotnie, dla zmiennej przyjmującej kolejno kaŝdą wartość z zakresu od początek do koniec. Pierwsza instrukcja jest stosowana dla zliczania w górę" (początek jest nie mniejszy niŝ koniec). JeŜeli koniec jest nie mniejszy niŝ początek, tj. chcemy zliczać w dół", powinniśmy uŝyć zapisu drugiego. program petla_for; { Program wpisuje liczby od 1 do 10, a następnie w dół - od 10 do 1. } i : Byte; for i := 1 to 10 do { zliczamy w gore od 1 do 10 } 3
write(i, ' '); writeln; for i := 10 downto 1 do {a następnie w dół od 10 do 1 } write(i, ' '); writeln; readln; end. Aby oddzielić ciąg rosnący od malejącego, posłuŝyliśmy się instrukcją writeln bez parametrów. Powoduje ona po prostu przejście do nowego wiersza. Pogram cw; {Program wypisuje liczby naturalne mniejsze od 100 } {i podzielne przez 11, wyznaczając je metodą "siłową". } i : Byte; : for i := 1 to 100 do if (i mod 11 = 0) then { liczba podziel na przez 11 } writeln(i); readln; Przypomnijmy wzór na N-ty wyraz ciągu fibonacciego: 0 dla N = 0 F(N) = 1 dla N= 1 F(N-2) + F(N-1) dla N >1 { Program oblicza N-ty wyraz ciągu Fibonacciego. } N, i : Byte: Poprzedni, Przedpoprzedni, Pomoc : Longint; write( Podaj numer wyrazu ciągu do wyliczenia: '): readln(n); if (N < 0) then { nie ma wyrazów o numerze ujemnym} writeln( Nie moŝna policzyć ', N, ' wyrazu ciągu Fibonacciego.' ) 4
else if (N = 0) then { wyraz zerowy jest równy zero } writeln( F(, N, ')=0') else if (N = 1) then { wyraz pierwszy jest równy jeden } writeln( F(, N,')=1') else Przedpoprzedni := 0; Poprzedni := 1: for i := 2 to N do { liczymy iteracyjnie dla N-tego wyrazu} Pomoc := Przedpoprzedni; Przedpoprzedni := Poprzedni; Poprzedni := Poprzedni + Pomoc; End; Writeln( F(, N, ')=', Poprzedni) readln; end. 5. Pętle repeat i while Pętla while ma postać: while warunek do { blok instrukcji } zaś, jej istotę najlepiej oddaje przetłumaczenie na język polski: Dopóki jest spełniony warunek, wykonuj blok instrukcji. Pętla repeat ma postać: repeat { blok instrukcji } until warunek Ponownie tłumacząc to na polski, otrzymujemy: Powtarzaj blok instrukcji, aŝ zostanie spełniony warunek. Jak widać, obie pętle robią to samo i moŝna by zapytać, jaka jest właściwie między nimi 5
róŝnica. Tkwi ona w miejscu sprawdzania warunku. W pętli while sprawdzany jest on na początku, czyli przed pierwszym wykonaniem instrukcji, zaś w pętli repeat na końcu przebiegu, czyli po pierwszym wykonaniu. Wynika stąd, Ŝe w pętli repeat instrukcje muszą wykonać się najmniej raz, natomiast w pętli while mogą nie wykonać się ani razu. program cw; {Program czyta kolejne liczby i liczy ich sumę aŝ do napotkania liczby 0. } Const Suma : Real = 0; Liczba : Real; Begin repeat writet( Dotychczasowa suma: ', Suma:10:2, '. Podaj liczbę: '); readln( Liczba); Suma := Suma + Liczba; until (Liczba = 0); writeln; writeln('całkowita suma: ', Suma:10:2); readln; end. Analizując strukturę programu, moŝna zauwaŝyć, Ŝe liczba oznaczająca koniec danych jest równieŝ dodawana do sumy. W naszym przypadku jest to na szczęście zero, jednak gdybyśmy chcieli przyjąć jako znacznik końca inną wartość, naleŝałoby zapobiec uwzględnieniu go w sumie. MoŜna to zrobić albo poprzez instrukcję warunkową (która przed sumowaniem sprawdzałaby, czy liczba nie jest znacznikiem końca), albo poprzez odjęcie liczby po wyjściu z pętli. Napisz program, który znajdzie największy wspólny podzielnik liczb A i B. program cw; { Program znajduje największy wspólny podzielnik liczb A i B. } A, B, Pom : Integer; 6
write('podaj A: '); readln(a); write('podaj B: '); readln(b); write( NWD(, A. '. '. B, ') = '): while (A <> B) do if (A < B) then { jeśli A jest mniejsze od B, zamień je miejsca Pom := A; A :- B; B := Pom; end: A := A - B; end: writeln(a); readln; end. Znowu podpieramy się zmienną Pom, która słuŝy do zamiany wartość: A i B w przypadku, gdy A jest mniejsze. Wątpliwości moŝe budzić równieŝ sposób wypisania wyniku część na początku, przed obliczeniami, a część po nich. PoniewaŜ chcemy, by przy wypisywaniu wyniku pojawiły się teŝ dane wejściowe, a program operuje na wprowadzonych liczbach i zmienia wartość, wyprowadzenie ich juŝ po zakończeniu obliczeń spowodowałoby problem. W takiej sytuacji naleŝałoby zapamiętać wpisane dane w dodatkowych dwóch zmiennych pomocniczych, aby potem móc je wypisać. A po co, skoro moŝna wypisać je od razu i nie pamiętać? program cw; { Program oblicza pierwiastki równań kwadratowych aŝ do podania A = A. B. C : Real; Delta, Xl, X2 : Real; repeat writeln('podaj współczynniki równania kwadratowego.'); write('podaj A: '); readln(a); if (A <> 0) then write( Podaj B: '); readln(b); write( Podaj C: '); readln(c); Delta : = Sqr(B) - 4*A*C; 7
if (Delta < 0) then writeln('równanie nie ma pierwiastków rzeczywistych') else if (Delta = 0) then Xl : = -B/(2*A); writeln('równanie ma jeden pierwiastek rzeczywisty; ', Xl;10;5 end else Xl := (-B - Sqrt(Delta))/(2*A); X2 := (-B + Sqrt(Delta))/(2*A); writeln('równanie ma dwa pierwiastki rzeczywiste: ', Xl:10:5, ','. X2;10:5); writeln; until (A = 0); end. ZauwaŜmy, Ŝe program sprawdza, czy współczynniki jest zerowy, a jeśli tak, zwalnia uŝytkownika z konieczności wpisywania pozostałych współczynników. Program cw; {Program znajduje największe wspólne podzielniki podawanych {Liczb tak długo, jak uŝytkownik będzie chciał. } A. B, Pom : Integer; Znak : Char; Begin repeat writeln; write('podaj A: '); readln(a); write('podaj B: '); readln(b); write( NWD(, A, ', '. B, ') = '); while (A <> B) do if A < B then 8
Pom := A; A := B: B := Pom; A ;= A - B; writeln(a): write('czy chcesz liczyć dalej (T/N) '); readln(znak); until (Upcase(Znak) = 'N'); end. 6. Instrukcja wyboru (Case..of) Instrukcja ta posiada następującą składnię: CASE wyraŝenie OF wartość1 : Instrukcja1; wartość2 : Instrukcja2;... END; lub CASE wyraŝenie OF wartość1 : Intrsukcja1; wartość2 : Instrukcja2;... ELSE Instrukcja3 End; Zbadać, czy wczytany znak jest samogłoską, spółgłoską polską lub jedną z liter obcych: q, x, v. Algorytm: Do badania znaku przy tylu moŝliwościach wyboru doskonale nadaje się mechanizm oferowany przez instrukcję wyboru. Aby zabezpieczyć się przed nieokreślonym działaniem tej instrukcji, naleŝy wcześniej zbadać, czy czytany znak jest w ogóle literą. Program: W programie dodatkowo drukujemy dla kontroli wczytaną daną. 9
PROGRAM litery; VAR Znak: char; BEGIN writeln( Program do rozpoznawania liter ); writeln( Podaj znak ); read(znak); writeln(znak); IF ( a <=znak) AND (znak <= z ) THEN {litera} CASE znak OF a, e, i, o, u, y : writeln( samogłoska ); q, v, x : writeln( spółgłoska obca ); b, c, d, f, g, h, j, k, l, m, n, p, r, s, t, w, z : writeln( spółgłoska polska ); END ELSE writeln( to nie była litera ) END. Program sprawdza czy podany przez uŝytkownika znak to mała lub duŝa litera, bądź cyfra. USES CRT; VAR znak:char; BEGIN clrscr; readln(znak); case ORD(znak) of 97..122: writeln('podales mala litere ',ORD(znak)); 65..90: writeln('podales duza litere ',ORD(znak)); 48..57: writeln('podales cyfre ',ORD(znak)); readln; END. 10