![]() |
Turbo Pascal.
|
![]() |
Instrukcja warunkowa
Aby uniknąć błędu wynikającego z próby pierwiastkowania liczby ujemnej, wypadałoby umieścić w naszym programie zastrzeżenie w postaci "jeżeli wyznacznik jest większy od zera to wykonaj dalsze obliczenia, w przeciwnym przypadku wypisz odpowiedni komunikat". Przekładając to na język angielski i nieco uogólniając, otrzymujemy strukturę instrukcji warunkowej:
if warunek
then instrukcja-1
else instrukcja-2W powyższym zapisie warunek jest niczym innym, jak wyrażeniem dającym w wyniku wartość true lub false, na ogół wykorzystującym znane Ci już operatory relacyjne (mówiąc po ludzku, jest to zwykłe porównanie). Instrukcje opisują czynności, które powinny być wykonane po spełnieniu lub niespełnieniu warunku, przy czym część zaczynająca się od słowa kluczowego else nie jest obowiązkowa (tj. nie musisz określać "wariantu awaryjnego").
Instrukcja warunkowa, dostępna praktycznie w każdym języku programowania, stanowi podstawowe narzędzie umożliwiające podejmowanie decyzji w zależności od aktualnych warunków, czyli wbudowywanie w program "inteligencji", pozwalającej mu zachować się odpowiednio do sytuacji. Spróbujmy wkomponować instrukcję warunkową w nasz poprzedni program:
program Nowe_Rownanie_Kwadratowe; { Program rozwiązuje równanie kwadratowe metodą wyznaczników } { uwzględniając możliwość ujemnego znaku wyznacznika } var a, b, c : real; { współczynniki } delta : real; { wyznacznik } x1, x2 : real; { pierwiastki } begin writeln('Program rozwiazuje rownanie kwadratowe') writeln('a*x^2 + b*x + c'); write('Podaj wspolczynnik a: '); { wprowadź współczynniki } readln(a); write('Podaj wspolczynnik b: '); readln(b); write('Podaj wspolczynnik c: '); readln(c); delta := sqr(b) - 4*a*c; { oblicz wyznacznik } if delta >= 0 then { wyznacznik OK } begin { wykonujemy obliczenia } x1 := (-b + sqrt(delta))/(2*a); { oblicz pierwiastki } x2 := (-b - sqrt(delta))/(2*a); writeln('Pierwiastki:'); { wyświetl pierwiastki } writeln('x1 = ', x1:12:4); writeln('x2 = ', x2:12:4); end { tu NIE MA średnika! } else { wyznacznik ujemny } writeln('Rownanie nie ma pierwiastkow rzeczywistych.'); readln; end. Postać warunku jest w naszym przypadku oczywista:
if delta >=0
czyli "jeżeli wyznacznik nie jest mniejszy od zera...". Zauważ, że jeśli warunek jest spełniony, należy wykonać więcej niż jedną instrukcję, a zatem cała grupa instrukcji zajmujących się obliczaniem i wyświetlaniem pierwiastków musi zostać otoczona słowami kluczowymi begin i end, oznaczającymi tzw. instrukcję złożoną, czyli zestaw instrukcji wykonywanych jako jedna całość. Zapominanie o tym wymaganiu jest jednym z pospolitszych błędów popełnianych przez programistów pascalowych (nie tylko początkujących) i może prowadzić do niezbyt przyjemnych błędów wykonania. Oto przykład:
if n <> 0 then LiczbaProbek := n; srednia := suma/LiczbaProbek; Powyższy fragment powinien przypisywać zmiennej LiczbaProbek wartość n, a następnie obliczać srednia jako suma podzielona przez LiczbaProbek, gwarantując, że w przypadku n równego zero dzielenie nie będzie wykonywane. Ponieważ jednak przypisania nie zostały połączone w instrukcję złożoną, dla n równego zeru pierwsze przypisanie nie wykona się, a zatem zmienna LiczbaProbek będzie miała wartość nieokreśloną. Może to być zero (wówczas wykonanie programu zostanie przerwane) lub dowolna wartość, co oczywiście doprowadzi do zupełnie bezsensownego wyniku. Prawidłowa postać powyższej instrukcji będzie wyglądała następująco:
if n <> 0 then begin LiczbaProbek := n; srednia := suma/LiczbaProbek; end; Wróćmy do naszego równania. Zauważ, że w pewnym szczególnym przypadku - gdy wyznacznik jest równy zeru - ma ono tylko jeden pierwiastek: jest tak dla równania
x2 + 2x + 1
którego podwójnym pierwiastkiem jest liczba -1. W tym przypadku musimy uwzględnić trzy możliwości, w zależności od wartości wyznacznika:
Wyznacznik Pierwiastkiwiększy od zera
równy zeru mniejszy od zera brak pierwiastków rzeczywistych Ponieważ pojedyncza instrukcja warunkowa potrafi obsłużyć tylko dwie wzajemnie się wykluczające sytuacje, aby uwzględnić wszystkie warianty, niezbędne jest zagnieżdżenie dwóch takich instrukcji. Schemat postępowania pokazany jest poniżej; w ramach ćwiczeń proponuję Ci samodzielne dokonanie odpowiednich modyfikacji w programie.
if delta < 0 then { brak pierwiastków rzeczywistych } else if delta = 0 then { oblicz i wypisz pojedynczy pierwiastek } else { odnosi się do drugiego if-a } { oblicz i wypisz obydwa pierwiastki } W przypadku większej liczby wariantów takie "piętrowe" konstrukcje stają się nieporęczne, trudne w interpretacji i podatne na błędy. Zastanów się na przykład, jak wyglądałaby instrukcja warunkowa wypisująca na ekranie nazwę dnia tygodnia danego numerem (niech 1 oznacza poniedziałek). Może tak:
if dzien = 1 then writeln('Poniedzialek')
else if dzien = 2 then writeln('Wtorek')
else if ...Co prawda używanie pełnej formy instrukcji warunkowej (if-then-else) nie jest tu konieczne i słowa else można usunąć (pamiętając o średnikach), jednak w dalszym ciągu powyższy twór będzie co najmniej nieelegancki. Skutecznym sposobem obsługi wyborów wielowariantowych jest instrukcja wyboru case, odpowiadająca z grubsza "stercie" zagnieżdżonych instrukcji warunkowych:
case przełącznik of wartość-1 : akcja-1; wartość-2 : akcja-2; ... else akcja-domyślna end; Powyższa struktura jest swoistą tablicą akcji odpowiadających poszczególnym wartościom zmiennej przełącznik i doskonale nadaje się do realizacji wielowariantowych wyborów, których klasycznym przykładem jest menu. Zauważ, że oprócz akcji skojarzonych z poszczególnymi wartościami przełącznika masz możliwość określenia akcji domyślnej, realizowanej w przypadku wystąpienia wartości nie znajdującej się w naszej "tablicy". Odpowiada za nią słowo kluczowe else umieszczone na końcu instrukcji. Pewnym ograniczeniem narzucanym przez instrukcję case jest wymaganie, by zmienna przełącznik była typu porządkowego (tak więc nie będziemy mogli zastosować jej w naszym programie, w którym wyznacznik jest liczbą rzeczywistą). Ułatwieniem natomiast jest możliwość "grupowego" definiowania wartości odpowiadających poszczególnym akcjom, np.:
case liczba_interesantow of 0 : mozna_wyjsc_do_fryzjera; 1, 2 : niech_czekaja; 3..6 : trzeba_obsluzyc; else wypisz('INWENTARYZACJA') end; Wartości odpowiadające poszczególnym akcjom mogą być wyliczane jawnie lub podawane w postaci zakresów (od..do), o ile tylko tworzą ciągłą grupę. Musisz również pamiętać, że - w odróżnieniu od instrukcji warunkowej - przed słowem else możesz postawić średnik.
I to by było na tyle, co oczywiście nie znaczy, że możesz spocząć na laurach. Miło jest mieć program potrafiący rozwiązać równanie kwadratowe, jednak znacznie przyjemniejsze byłoby posiadanie narzędzia do rozwiązywania bardziej skomplikowanych równań. Ale czy to aby nie za trudne? Bynajmniej...
Zapamiętaj
- Do warunkowego wykonywania operacji służy w programach pascalowych instrukcja warunkowa if-then-else.
- Używając instrukcji warunkowych musisz pamiętać o właściwym stosowaniu instrukcji złożonej oraz o braku średnika przed słowem else.
- Aby obsłużyć więcej niż dwa warianty, możesz użyć zagnieżdżonych instrukcji warunkowych.
- Jeśli wyborem steruje wartość typu porządkowego, lepszym rozwiązaniem jest użycie instrukcji wyboru case.
Poprzedni | Spis treści | Następny | Wersja spakowana |