Fortran/Instrukcje sterujące

Logika

edytuj

Na początku warto zastanowić się, na podstawie czego komputer może podejmować decyzję. Zwykle odbywa się to na podstawie jednej z dwóch wartości - prawdy, oznaczanej w Fortranie jako .TRUE. oraz fałszu, oznaczanego jako .FALSE.. Mamy również pewien zbiór operacji logicznych. Oto one:

operacja nazwa
.NOT. negacja
.AND. koniunkcja
.OR. alternatywa
.EQV. równoważność
.NEQV. zaprzeczenie równoważności, alternatywa wykluczająca

Działanie tych operatorów najlepiej zademonstruje ta tabelka:

A B .NOT. A A .AND. B A .OR. B A .EQV. B A .NEQV. B
.TRUE. .TRUE. .FALSE. .TRUE. .TRUE. .TRUE. .FALSE.
.TRUE. .FALSE. .FALSE. .FALSE. .TRUE. .FALSE. .TRUE.
.FALSE. .TRUE. .TRUE. .FALSE. .TRUE. .FALSE. .TRUE.
.FALSE. .FALSE. .TRUE. .FALSE. .FALSE. .TRUE. .FALSE

Porównując dwie liczby możemy np. ocenić ich wzajemną relację, tzn. czy liczba a jest większa, mniejsza a może równa. W języku Fortran możemy do tego celu użyć dwóch grup operatorów. Jedna grupa znana jest zapewne programistom, tworzącym swe programy w językach C oraz Pascal (tzn. >, <, = (lub == w C), >=, <=). Oprócz nich w języku Fortran możemy także używać:

operator opis
.LT. ang. less than - inaczej <
.LE. ang. less equal - inaczej <=
.GT. ang. greater than - inaczej >
.GE. ang. greater equal - inaczej >=
.EQ. ang. equal - inaczej == (lub = w Pascalu)
.NE. ang. not equal - inaczej != (lub <> w Pascalu)


Jest to pierwsza instrukcja, jaką poznasz. Jezyk Fortran dawniej wręcz wymuszał użycie konstrukcji GOTO. Aż do wersji Fortranu 66 brakowało konstrukcji pętli WHILE. Trzeba było sobie radzić przez skok do początku refrenu pętli właśnie za pomocą konstrukcji GOTO. W Fortranie 77 wystąpienie błędu operacji wejścia/wyjścia powoduje skok do wskazanego miejsca w programie.

Jedyną zaletą instrukcji GOTO jest możliwość dowolnego kształtowania przebiegu sterowania w programie. Niestety odbywa się to prawie zawsze kosztem czytelności kodu. Konstrukja GOTO powinna być stosowana z umiarem, aby nie stracić kontroli nad rozumieniem programu.

Czytając wprowadzenie do tego podręcznika zapamiętałeś (a jeśli nie, to masz tutaj link), że w języku Fortran (do wersji 77 włącznie) ma znaczenie liczba spacji. Wiesz także, że pierwsze 1-5 spacji przeznaczone jest na pewną liczbę z zakresu od 1 do 99999. Owe liczby nie są tylko po to, aby numerować linijki kodu źródłowego (zresztą i tak czasami byłoby ich za mało). Oznaczają one mniej więcej to, co etykiety w języku C. To dzięki nim możemy określić punkt w kodzie programu, do którego możemy potem "przeskoczyć". Do "skakania" po kodzie programu służy instrukcja GOTO. Oto przykład użycia:

 program skok
   goto 10
   write (*,*) "Skakanka..."
10 continue
end program skok

Efekt działania tego programu jest oczywisty... program po prostu zakończy swe działanie. W kodzie programu została także użyta instrukcja CONTINUE, która powoduje po prostu dalsze wykonywanie programu.

Nasz program powinien mieć możliwość reagowania na zawartość np. zmiennych. Przyjrzyjmy się zatem instrukcji IF. Służy ona do zdefiniowania czynności, które mają być wykonane w momencie prawdziwości jakiegoś warunku. Użycie instrukcji IF wygląda mniej więcej tak:

  IF (warunek) instrukcje do wykonania

Ważne jest przy tym, aby instrukcje te były wpisane w tej samej linijce, co IF - w przeciwnym wypadku kompilator zasygnalizuje błąd.

IF - THEN

edytuj

Jedna linijka to mało. Czasami potrzebujemy wykonać tak dużo instrukcji, że po prostu nie zmieszczą się w jednej linijce. Do tego celu powstała konstrukcja IF - THEN. Ogólnie rzecz biorąc jej zastosowanie wygląda tak:

 IF (warunek) THEN
   instrukcje do wykonania
 END IF

IF - THEN - ELSE

edytuj

W tworzeniu programu zdarzają się też przypadki, w których program powinien zareagować także na sytuację przeciwną do warunku. Wtedy z pomocą przychodzi konstrukcja IF - THEN - ELSE:

 IF (warunek) THEN
   instrukcje do wykonania
 ELSE
   instrukcje do wykonania w przeciwnym wypadku
 END IF

SELECT - CASE

edytuj

Jeśli musimy zareagować na większą ilość warunków, to zamiast powtarzać konstrukcję if-else lepiej użyć select-case. Użycie tej konstrukcji jest bardzo proste:

 select case (wyrażenie)
               case (warunek1)
                 instrukcje do wykonania w przypadku wyrażenie == warunek1
               case (warunek2) 
                 instrukcje do wykonania w przypadku wyrażenie == warunek2
               [case default
                 instrukcje do wykonania w innych przypadkach ]
 end select 

Zastosowanie tej pętli w praktyce jest bardzo proste. Przeanalizujmy następujący przykład:

 program test
   implicit none
 
   integer :: i
   i = 123
   select case (i)
         case (123, 125)
            print *, "i=123 lub i=125"
         case (10:30)
            print *, "i zawiera się w przedziale od 10 do 30"
         case default
            print *, "inny przypadek"
   end select
 
 end program test

Pętle

edytuj

Może się zdarzyć, że w twoim programie jakaś czynność (bądź kilka czynności) będzie musiała być wykonana kilka razy pod rząd. Oczywiście nie ma sensu kilka razy kopiować i wklejać tego samego kodu. W takich przypadkach z pomocą przychodzą nam pętle. Pętla jest to instrukcja, która umożliwia wielokrotne powtarzanie tego samego kodu. W języku Fortran wyróżnia się kilka rodzajów pętli. Zostaną one omówione poniżej.

Najprostszą pętlą jest pętla do. Wygląda ona tak:

  [nazwa] do zmienna=wartość początkowa, wartość końcowa [,skok co]
    instrukcje
  end do [nazwa]

Aby np. policzyć do dziesięciu, licząc po dwa możemy napisać coś takiego:

  do i=0, 10, 2
    print *, "Doliczyłem do ",i
  end do

Jak widzisz, nie musisz wcześniej deklarować zmiennej i. Kompilator automatycznie użyje typu integer. Minusem tej pętli jest to, że krokiem może być tylko liczba całkowita. Za to wielkim plusem jest automatyczne sprawdzanie zakresów. Np. pisząc pętlę od 0 do 10 z krokiem 3 ostatnią wartością będzie 9.

do-if-exit

edytuj

Pętla ta wykonuje się w nieskończoność, dopóki nie wystąpi instrukcja exit. Instrukcja ta jest zwykle efektem spełnienia jakiegoś warunku. Zwykle wygląda to tak:

 [nazwa] do
    instrukcje
    if (warunek logiczny) exit
    instrukcje
 end do [nazwa]

W przeciwieństwie do pętli omówionej powyżej, możemy tutaj użyć typu real jako licznika. Oto przykład:

 real :: p=0
   do
     p = p+0.5
     if (p>10) exit
     print *, "A teraz jest: ",p
   end do