* Önsöz
* Fortran'a Giriş
* Fortran'nın Temelleri
* Basit ve Formatlı Okuma/Yazma
* Temel Kütüphane Fonksiyonları
* Karşılaştırma Deyimleri
* Döngüler
* Alt Programlar I
* Alt Programlar II
* Diziler
* Dinamik Diziler
* Gösterici (Pointer) Kavramı
* Katarlar (Stringler)
* Yapısal Veri Tipleri
* Dosya Yönetimi
* Modül Kavramı
* Sayısal Tipler (KINDs)
* Bit Düzeyinde Çalışmak
* Kütüphane Fonksiyonları Listesi
* Yararlanılan Kaynaklar
* - - -
* Karmaşık Sayılar
* Tarih-Saat Fonksiyonları
* Rastgele Sayılar
* Katar - Sayı Dönüşümleri
* Komut Satırı İşlemleri
* Co-Array Fortran
* Derleme Seçenekleri
* Fortran ve C
* Sayılar Kuramı
* Analiz
* Lineer Cebir
Fortran 90/95 Derleyicileri
|
* Salford (silversoft FTN95)
* G95
* GFORTRAN
* programlama.com
* Fortran (wikipedia)
* fortran.gantep.edu.tr
* g95.org
* Hot scripts
* E-posta
|
|
Bölüm 7: Alt Programlar I
###################- (%95)
|
Giriş
Programla dillerinde alt program, belirli sayıda verileri kullanarak bunları işleyen ve
bir sonuç üreten komut grubudur. Fortran programlama dili'de alt programların birleştirilmesi kavramına dayanır.
Bu özellik bütün Yapısal Diller'in (C, Fortran, Pascal, ...) temelini oluşturur.
Yapısal Diller'e hakim olmak için alt program oluşturmayı ve kullanmayı iyi öğrenmek gerekir.
Fortran'da alt programlar FUNCTION ve SUBROUTINE
deyimleri ile oluşturulur. Bu bölümde, Fortran 90+ Programlama Dili'ndeki
bu deyimlerle oluşturalan alt programlar, sonraki bölümde (Bölüm 8)
esnek argümanlı ve anahtar argumanlı alt programlar irdelenecektir.
7.1 FUNCTION Deyimi
Function bir fonksiyon oluşturma deyimidir.
Her fonksiyonun bir adı ve fonksiyona gelen değerleri gösteren argumanları
(bağımsız değişkenleri) vardır. Genel olarak bir fonksiyon Şekil 7.1'deki gibi bir kutu ile temsil edilebilir:
Şekil 7.1: Bir fonksiyonun kutu gösterimi
Fonksiyonların girdilerine parametreler yada argumanlar denir. Bir fonksiyon bu parametreleri alıp bir
işleme tabi tutar ve bir değer hesaplar. Bu değer, çıktı veya geri dönüş değeri (return value) olarak adlandırılır.
Unutmayın ki, bir fonksiyonun kaç girişi olursa olsun sadece bir çıkışı vardır.
Fortran, kullanıcısına bu türden fonksiyon yazmasına izin verir. Genel bildirim şöyledir:
tip FUNCTION isim(arguman listesi)
...
isim = bir ifade
...
END FUNCTION isim
burada
- tip, fonksiyonun üreteceği değerin veri tipi (INTEGER, REAL gibi)
- isim, Fonksiyonunun adınu tutar ve geçerli bir tanımlayıcı (valid identifier) olmalıdır.
- arguman listesi, birbirinden virgül ile ayrılmış fonksiyon argumanları.
- isim = bir ifade, kullanılması zorunludur ve fonksiyonun döndüreceği değer burada belirlenir.
- END FUNCTION deyimi fonksiyon bloğunun sonunu işaret eder.
Bundan sonra yazılan isim'in kullanımı isteğe bağlıdır (kullanılması zorunlu değildir).
Örneğin iki tamsayının toplamını hesaplayacak bir fonksiyon şöyle tanımlanabilir:
INTEGER FUNCTION Topla(A, B)
INTEGER, INTENT(IN) :: A,B
Topla = A + B
END FUNCTION Topla
veya
FUNCTION Topla(A, B)
INTEGER, INTENT(IN) :: A,B
INTEGER :: Topla
Topla = A + B
END FUNCTION Topla
veya
INTEGER FUNCTION Topla(A, B)
INTEGER :: A, B
Topla = A + B
END FUNCTION Topla
INTENT(IN) özniteliği (attribute), Topla fonksiyonunun giriş argümanları (A ve B)
fonksiyon içinde olası bir değişime maruz kalmasını engellemek için konmuştur.
INTENT(IN), kullanımı uzman Fortran programcıları tarafından şiddetle tavsiye olunur.
Bir fonksiyon, bildirilirken ve ana programdan çağrılırken iki yöntem izlenir.
- İç (internal) fonksiyon bildirimi
- Dış (external) fonksiyon bildirimi
İç Fonksiyon Bildirimi
Fonksiyon bloğu ana programda, CONTAINS ve END PROGRAM deyimleri arasına yerleştirilir.
Bu durumda, Topla fonksiyonu aşağıdaki gibi çağrılır.
Program 7.1: İç fonksiyon tanımlaması
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
|
PROGRAM Toplama
!--------------------------------------------------------
! 07prg01.f95
! İki sayının toplamını Topla fonksiyonu ile hesaplar.
!--------------------------------------------------------
IMPLICIT NONE
INTEGER :: X, Y, Z
PRINT *,"Iki sayı girin:"
READ *, X, Y
Z = Topla(X,Y)
PRINT *,"Toplam = ", Z
CONTAINS
INTEGER FUNCTION Topla(A, B)
INTEGER, INTENT(IN) :: A,B
Topla = A + B
END FUNCTION Topla
END PROGRAM |
ÇIKTI
Iki sayı girin:
2 8
Toplam = 10
|
Programda, klavyeden okunan X ve Y değişkenleri fonksiyonuna parametre olarak aktarılmıştır.
Bu değişkenlerin isimleri ile Topla fonksiyonunda kullanılan değişkenlerin
(A ve B) isimleri aynı olması zorunlu değildir.
Burara X ve Y değişkenlerinin içerikleri (yani tutukları sayısal değerler) sırasıyla A ve B değişkenlerine kopyalanmıştır.
12. satırda Z adlı tamsayı değişkenine Topla fonksiyonunun dönüş değeri (A + B değeri) atanmıştır.
Aşağıdaki programda, Faktor fonksiyonu ile 0'dan 10'a kadar olan sayılar ve
faktoriyellerinin ekrana yazdırılması gösterilmiştir.
Program 7.2: Faktoriyel hesabı
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
|
PROGRAM Faktoriyel
!--------------------------------------------------------
! 07prg02.f95
! Faktor() fonksiyonu ile 0'dan 10'a kadar olan sayıları
! ve faktoriyellerini ekrana basar.
!--------------------------------------------------------
IMPLICIT NONE
INTEGER :: I
DO I = 0, 10
PRINT *, I,"! = ", Faktor(I)
END DO
CONTAINS
INTEGER FUNCTION Faktor(N)
INTEGER, INTENT(IN) :: N
INTEGER :: J
Faktor = 1
DO J=1,N
Faktor = Faktor * J
END DO
END FUNCTION Faktor
END PROGRAM |
ÇIKTI
0 ! = 1
1 ! = 1
2 ! = 2
3 ! = 6
4 ! = 24
5 ! = 120
6 ! = 720
7 ! = 5040
8 ! = 40320
9 ! = 362880
10 ! = 3628800
|
Dış Fonksiyon Bildirimi
Fonksiyon bloğu ana programın dışında bildirilmek mümkündür. Bunun için önce INTERFACE bloğu oluşturulup fonksiyon
örneği (prototype) ana programda bildirilmelidir. Dış bildirim kullanılarak, Topla fonksiyonu aşağıdaki gibi çağrılır.
Program 7.3: Dış fonksiyon tanımlaması
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
|
PROGRAM Toplama
!--------------------------------------------------------
! 07prg03.f95
! İki sayının toplamını Topla fonksiyonu ile hesaplar.
!--------------------------------------------------------
IMPLICIT NONE
! fonksiyon prototipi
INTERFACE Topla_Ornegi
INTEGER FUNCTION Topla(A, B)
INTEGER, INTENT(IN) :: A,B
END FUNCTION Topla
END INTERFACE Topla_Ornegi
INTEGER :: X, Y, Z
PRINT *,"Iki sayı girin:"
READ *, X, Y
Z = Topla(X,Y)
PRINT *,"Toplam = ", Z
END PROGRAM Toplama
! Fonksiyon bildirimi
INTEGER FUNCTION Topla(A, B)
INTEGER, INTENT(IN) :: A,B
Topla = A + B
END FUNCTION Topla |
ÇIKTI
Iki sayı girin:
2 8
Toplam = 10
|
7.2 SUBROUTINE Deyimi
Fonksiyonlar gelen argümanlara göre sadece bir değer dödürebilir. Bir alt programla birden çok değer döndürülmek istendiğinde
SUBROUTINE deyimi kullanılır. Kutu gösterimi şekil 7.2'de verilen bu türden alt programalar CALL deyimi kullanılarak çağılır.
Şekil 7.2: SUBROUTINE tipi bir alt programın kutu gösterimi
SUBROUTINE oluşturmanın genel yazım biçimi şöyledir:
SUBROUTINE isim(argüman listesi)
.
.
.
END SUBROUTINE isim
FUNCTION ile karşılaştırıldığında, SUBROUTINE tipi alt programın bir tipi olmadığına ve ismin
herhangi bir ifadeye eşitlenmediğine dikkat ediniz.
Bu kurala göre kartezyen koordinatlarda verilen bir (x, y) noktasının, kutupsal (polar) koordinattaki karşılığını (r, θ) döndüren bir
bir SUBROUTINE şöyle tanımlanabilir:
SUBROUTINE KartezyenPolar(X, Y, R, Teta)
REAL, INTENT(IN) :: X, Y
REAL, INTENT(OUT) :: R, Teta
R = SQRT(x**2+Y**2)
Teta = ATAN(Y/X)
END SUBROUTINE KartezyenPolar
Burada X ve Y SUBROUTINE'nin giriş, R ve Teta hesaplanan çıkış argümanlarıdır.
Bu subroutine aşağıdaki gibi çağrıldığında
CALL KartezyenPolar(3.0, 4.0, mesafe, aci)
PRINT *,mesafe, aci
(3,4) noktasının polar karşılığı (mesafe = 5.0 aci = 0.927295 değerleri) ekrana basılır.
SUBROUTINE'ler de fonksiyonlar gibi iç ve dış bildirim ile tanımlanabilir. İki bildirimin kullanılması aşağıdaki
programlarda verilmiştir.
Program 7.4: İç SUBROUTINE bildirimi
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
|
PROGRAM Cevrim
!--------------------------------------------------------
! 07prg04.f95
! Kartezyen-polar çevrimi (iç Subroutine ile)
!--------------------------------------------------------
IMPLICIT NONE
REAL, PARAMETER :: PI = 3.141593
REAL :: X, Y, R, T
PRINT *,"Bir (x, y) koordinatı girin:"
READ *, X, Y
CALL KartezyenPolar(X, Y, R, T)
T = T * 180.0/PI ! radyanı dereceye çevir
PRINT *,"(x,y) -> (r,teta) karşılığı = ", R, T
CONTAINS
SUBROUTINE KartezyenPolar(X, Y, R, Teta)
REAL, INTENT(IN) :: X, Y
REAL, INTENT(OUT) :: R, Teta
R = SQRT(x**2+Y**2)
Teta = ATAN(Y/X)
END SUBROUTINE KartezyenPolar
END PROGRAM Cevrim |
ÇIKTI
Bir (x, y) koordinatı girin:
3 4
(x,y) -> (r,teta) karşılığı = 5. 53.130093
|
Program 7.5: Dış SUBROUTINE bildirimi
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
|
PROGRAM Cevrim
!--------------------------------------------------------
! 07prg04.f95
! Kartezyen-polar çevrimi (iç Subroutine ile)
!--------------------------------------------------------
IMPLICIT NONE
! Prototip
INTERFACE KarPol
SUBROUTINE KartezyenPolar(X, Y, R, Teta)
REAL, INTENT(IN) :: X, Y
REAL, INTENT(OUT) :: R, Teta
END SUBROUTINE KartezyenPolar
END INTERFACE KarPol
REAL, PARAMETER :: PI = 3.141593
REAL :: X, Y, R, T
PRINT *,"Bir (x, y) koordinatı girin:"
READ *, X, Y
CALL KartezyenPolar(X, Y, R, T)
T = T * 180.0/PI ! radyanı dereceye çevir
PRINT *,"(x,y) -> (r,teta) karşılığı = ", R, T
END PROGRAM Cevrim
! Bildirim
SUBROUTINE KartezyenPolar(X, Y, R, Teta)
REAL, INTENT(IN) :: X, Y
REAL, INTENT(OUT) :: R, Teta
R = SQRT(x**2+Y**2)
Teta = ATAN(Y/X)
END SUBROUTINE |
ÇIKTI
Bir (x, y) koordinatı girin:
3 4
(x,y) -> (r,teta) karşılığı = 5. 53.130093
|
7.3 RETURN Deyimi
Bir fonksiyon ile üretilen değer yada bir suburoutine ile üretilen değer(ler)
END FUNCTION veya END SUBROUTINE deyimi ile karşılaşılınca döndürülür.
Ancak, bir fonksiyon (yada subroutine) bu deyimlere ulaşılmadan her hangi bir noktadan da
RETURN deyimi ile sonlandırılabilir.
Örneğin, aşağıdaki fonksiyon giriş argümanı (tamsayı N) [2, 12] aralığının dışında ise 1, aksi halde
N! değerini döndürür.
INTEGER FUNCTION Faktor(N)
INTEGER, INTENT(IN) :: N
INTEGER :: I
Faktor = 1
IF(N<1 .OR. N>12) RETURN
DO I = 2, N
Faktor = Faktor * I
END DO
END FUNCTION Faktor
7.4 Yapısal Programlama
Program içinde birden çok fonksiyon tanımlayıp kullanmak mümkündür. Fortran Programlama Dili fonksiyonların inşası dayalı bir dildir.
Bu özellik bütün Yapısal Programlama Dilleri'nin (Structred Programming) temelini oluşturur.
Birden çok fonksiyonun ana program tarafından nasıl çağrıldığını temsil eden blok diyagram Şekil 7.3'de gösterilmiştir.
Şekil 7.3: Ana programdan bir çok alt programın çağırılması.
Fonksiyonların sadece ana program tarafından çağrılması zorunlu değildir. Bir fonksiyon başka bir fonksiyon
tarafından da çağrılabilir. Buna dair bir örnek aşağıda verilmiştir.
<>Yilin_Gunu fonksiyonu, verilen bir tarihin yılın kaçıncı günü olduğunu hesaplar ve çağrıldığı yere gönderir. İnceleyiniz.
Program 7.6: Bir fonksiyonun başka bir fonksiyon tarafından çağrılması
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
|
PROGRAM Tarih
!--------------------------------------------------------
! 07prg06.f95
! Verilen bir tarihin yılın kaçıncı günü olduğunu
! hesaplar.
!--------------------------------------------------------
IMPLICIT NONE
INTEGER :: gun = 1 ! tarih: 01 Ağustos 2003
INTEGER :: ay = 8
INTEGER :: yil = 2003
PRINT *, gun, ay, yil, " tarihi yılın"
PRINT *, Yilin_Gunu(gun,ay,yil), ". günüdür"
CONTAINS
! yil artıl yıl ise 1 aksi halde 0 gönderir
INTEGER FUNCTION Artik(Yil)
INTEGER, INTENT(IN) :: Yil
Artik = 0
IF( mod(yil,4) ==0 .AND. &
mod(yil,100)/=0 .OR. &
mod(yil,400)==0 ) Artik = 1
END FUNCTION Artik
! Yılın kaçıncı günü olduğunu hesaplar ve o günü gönderirir
INTEGER FUNCTION Yilin_Gunu(Gun, Ay, Yil)
INTEGER, INTENT(IN) :: Gun, Ay, Yil
INTEGER :: I
INTEGER :: agun(12) = (/31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31/)
Yilin_Gunu = gun
DO I = 1, Ay-1
Yilin_Gunu = Yilin_Gunu + agun(I)
if(I==2) Yilin_Gunu = Yilin_Gunu + Artik(yil)
END DO
END FUNCTION
END PROGRAM Tarih |
ÇIKTI
1 8 2003 tarihi yılın
213 . günüdür
|
7.5 Örnekler
ÖRNEK 1: BINOM AÇILIMI
(a+b)n ifadesinin, binom açılım katsayıları aşağıdaki formüllle verilir:
Bunlar aslında Pascal Üçgeninin elemanları oluşturur.
n = 1 1
n = 2 1 2 1
n = 3 1 3 3 1
n = 4 1 4 6 4 1
n = 5 1 5 10 10 5 1
. .
. .
. .
Açılım katsayılarını bulmak için, iki fonksiyon tanımlıyacağız: Faktor(n) ve C(n, k).
Aşağıdaki program, bir döngü içerisinde, n = 1, 2, 3, 4, 5 ve 6 için binom katsayılarını ekrana basar.
Program 7.7: Binom açılımı
01:
02:
03:
04:
05:
06:
07:
08:
09:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
|
PROGRAM Binom_Acilimi
!--------------------------------------------------------
! 07prg04.f95
! Kartezyen-polar çevrimi (iç Subroutine ile)
!--------------------------------------------------------
IMPLICIT NONE
INTEGER :: n, k
DO n = 0, 6
DO k = 0, n
WRITE(*,FMT='(I3)',ADVANCE='No') C(n,k)
END DO
WRITE(*,*)
END DO
CONTAINS
! N! değerini döndürür
INTEGER FUNCTION Faktor(N)
INTEGER, INTENT(IN) :: N
INTEGER :: J
Faktor = 1
DO J=1,N
Faktor = Faktor * J
END DO
END FUNCTION Faktor
! C(n,k) kombinasyonunu hesaplar
INTEGER FUNCTION C(N, K)
INTEGER, INTENT(IN) :: N, K
C = faktor(n)/(faktor(k)*faktor(n-k))
END FUNCTION
END PROGRAM Binom_Acilimi |
ÇIKTI
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
|
ÖRNEK 2: XXX
ÖRNEK 3: XXX
|