OMÜ HAVACILIK VE UZAY BİLİMLERİ FAKÜLTESİ METEOROLOJİ MÜHENDİSLİĞİ BÖLÜMÜ MET103 BİLGİSAYAR PROGRAMLAMA I FİNAL SINAVI 11.01.2016 1. (6 puan) İnternetten, kod.txt isimli bir dosyayı Linux kurulu bir bilgisayardaki ~/Downloads dizinine indirmiş olduğunuzu varsayın. a) Kendi ev dizininizde açtığınız Linux terminalinde, kod.txt'nin bulunduğu dizine gitmek için yazılması gereken Linux terminali komutunu, b) kod.txt nin bulunduğu dizinde iken, bu dosyada bulunan Fortran90 kaynak kodunu Gedit'in Fortran90 kaynak kodu olarak okuyabilmesi (yani, Fortran90 sözcüklerini renklendirebilmesi) için dosya isminde yapılması gereken değişikliği yapacak Linux terminali komutunu yazınız. a) cd Downloads veya cd ~/Downloads cd ~/Downloads/kod.txt yanlış! Dizine gideceğiz, dosyaya değil (dosyaya cd yapılmaz, hata verir!) b) mv kod.txt kod.f90 (dosyanın ismini değiştirip uzantısını f90 yaptık) 2. (9 puan) Aşağıdaki Fortran90 kaynak kodu derlendiğinde, üç adet birbirinden bağımsız hata mesajı alınmaktadır. Bu hataların nedenini ve hataları gidermek için programda yapılması gereken değişiklikleri KISACA (üç cümleyle) açıklayınız (programı değiştirmeyiniz, yeniden yazmayınız, sadece açıklama yapınız). program uc_hata integer : x(5),i x=10 if (x(1)=10) print *,'Doğrudur.' do i=1,5 x(i)=30 i=i+1 end program uc_hata 1) Değişken deklare ederken bir tane değil iki tane : kullanılır. integer :: x(5),i olmalıydı. 2) Mantıksal ifadenin içindeki = işareti tek olmaz, == şeklinde çift olmalıdır veya.eq. şeklinde yazılmalıdır. Yani if (x(1)==10) print *,'Doğrudur.' veya if (x(1).eq.10) print *,'Doğrudur.' olmalıydı.
3) Sayaçlı do döngülerinde (burada do i=1,5 diye başlayan) kontrol değişkenini (burada i) döngü içinde değiştiremeyiz. Zaten her devirde kendisi bir artıyor. i=i+1 kaldırılmalıdır. DİKKAT! If, eğer tek bir komut içeriyorsa, then ve end if olmadan da kullanılabilir ve bu haliyle tek bir satır yer kaplar. Dolayısıyla if (x(1)==10) print *,'Doğrudur.' yazılabilir, bunda hata yoktur. Mantıksal ifadenin (then ve end if olsa bile) her zaman parantez içinde yazılmasına dikkat edilmelidir, yoksa ifade hata verir. DİKKAT! Tırnak içindeki metin ifadelerinde Türkçe karakter kullanılabilir. Kodun geri kalanında kullanılamaz.
3. (20 puan) Aşağıdaki Fortran90 programında kullanılan, dolayısıyla da tanımlanması gereken tüm değişkenleri ve sabitleri, ana program ve alt programlar içinde boş bırakılan satırlarda tanımlayınız (veya deklare ediniz, tanıtınız; hepsi aynı şey). baslangic, bitis ve pi değerlerini birer sabit olarak ve değerleri sırasıyla 1, 4 ve 3.14 olmak üzere; kullanılan diğer değerlerin hepsini birer değişken olarak tanımlayınız. Tüm sabit ve değişkenleri doğru tipte tanımlayınız. program degiskenler integer, parameter :: baslangic=1, bitis=4 integer :: x, i real :: y, hacimler(5), cap, yukseklik, koni_hacim logical :: s(50) character (len=3) :: h(150,200) x = 2 y = sqrt(real(x)) s =.true. s(25:50) =.false. h(1:99,100:200) = x10 h(100:150,1:10) = s20 do i=baslangic,bitis,1 hacimler(i) = real(x)/real(i) cap = 5.6 yukseklik = 3.6 hacimler(5)=koni_hacim(cap,yukseklik) function koni_hacim(r,h) real, parameter :: pi=3.14 real :: koni_hacim,r,h,yaricap yaricap = R/2 koni_hacim = pi*yaricap**2*h return end function koni_hacim subroutine yazilacak(hcm) real :: hcm, fazlasi, genislet call yazilacak(hacimler(5)) end program degiskenler fazlasi = 30.0 genislet = hcm+fazlasi print *, genislet end subroutine yazilacak
4. (14 puan) buradanoku.txt adlı dosya, Fortran90 kaynak kodunun yazıldığı dizinde bulunmakta ve aşağıda 4 tanesi gösterilen 10 adet satır içermektedir: 1 Ahmet 56.83 74.25 2 Damla 45.24 87.12 3 Cevahir 68.02 77.70... 10 Yusuf 75.42 51.50 Bu dosyadaki en uzun isim olan Cevahir, sağındaki ve solundaki sayılardan ikişer boşlukla ayrılmıştır. Ayrıca her bir satırdaki iki puan sütunu arasında da iki boşluk vardır. Dört sütun da sol taraflarından hizalanmıştır. Kaynak kodumuzda tanımlayacağımız sira, ad ve puan isimli üç değişkene, bu dosyadaki verileri, dosyadan okutmak suretiyle atamak istiyoruz. Sira değişkeni 1. sütun, ad değişkeni 2. sütun, puan değişkeni ise 3. ve 4. sütunlar oluşturmalıdır. Bu işi yapacak Fortran90 kodundaki (aşağıda) tüm eksikleri gideriniz. program okuttur integer, parameter :: kisi_sayisi=10 integer :: sira(kisi_sayisi), i real :: puan(kisi_sayisi,2) character (len=7) :: ad(kisi_sayisi) open(1,'buradanoku.txt') do i=1,kisi_sayisi read(1,40) sira(i), ad(i), puan(i,:) 40 format(i3,a9,f5.2,2x,f5.2) close(1) end program okuttur
5. (8 puan) Şekilde gösterilen prizma üzerindeki 18 noktanın her birinde, ölçüm yapıldığında hepsinde birden yapılmak üzere 10 farklı zamanda sıcaklık ölçümü yapılmıştır. a) Ölçülen tüm sıcaklık değerlerini, yer ve zaman bilgisiyle birlikte içeren T adlı değişkeni tanımlayan (deklare eden) Fortran90 ifadesini yazınız. b) Halka içine alınmış noktalarda 5. zamanda ölçülen sıcaklık değerlerini, daha önce tanımlanmış tek boyutlu ve iki değerli A adlı değişkene atayan Fortran90 ifadesini yazınız. a) real :: T(3,3,2,10) X doğrultusunda 3, Y doğrultusunda 3, Z doğrultusunda 2, zamanda da 10 nokta var. b) A = T(2:3,3,2,5) Belirtilen noktalar X boyutunda 2. ve 3. sırada, Y'de 3., Z'de 2., zamanda da 5. sırada bulunuyor. Soruda sizden Fortran90 ifadelerini yazmanız isteniyor. Sadece T(3,3,2,10) gibi şeyler yazmak yanlıştır. 6. (8 puan) Aşağıdaki Fortran90 programı derlenip çalıştırıldığında ekrana ne yazar? program kacyapar integer, parameter :: s=5 integer, dimension(s,s) :: A=20 integer :: i,j A(:,:)=A+30 print *, A(2,2:4:2) A(5:,:1)=80 do i=1,s do j=1,s if (A(i,j)>70) print *, A(i,j) end program kacyapar
A, 5'e 5'lik 2 boyutlu bir dizi (array) değişkeni. Başta tüm değerleri 20. Sonra tüm değerlerini ( A(:,:) ) 30 arttıyoruz ve tüm değerleri 50 oluyor. Bunlardan yalnızca iki tanesini seçiyoruz (2. satırdaki 2. ve 4. sütunlar), bunları yazdırıyoruz. 50 50 yazar. Sonra sadece A(5,1) değerini 80 yapıyoruz. Çünkü 5:, 5'ten başlat ve sona git demek, 5 zaten son indeks, dolayısıyla sadece 5'i alır. Aynı şekilde baştan başlayıp 1'e git dersek de sadece 1'i alırız ( :1 ) Döngü, sadece tek bir değeri 80 olan A'nın tüm değerleri üzerinden giderek 70'ten büyük olan değerle karşılaştığında yazmasını istiyor. Bu da sadece tek bir değerdir : A(5,1). Değeri de 80. Cevap: 50 50 80 7. (6 puan) Aşağıdaki Fortran90 programı derlenip çalıştırıldığında ekrana ne yazar? program dikkat integer :: a=12,b=5 real :: x,y,z x=a/b-1 y=a/b-2.0 z=real(a)/b+1 print 10, x print 10, y print 10, z 10 format(f3.1) end program dikkat Parantez yoksa, ilk önce bölme, sonra çıkarma yapılır. İşlem sırası! a/b, eğer iki değer de tam sayı (integer) ise (ki öyle), tam sayı sonucu vermek zorundadır. 12 / 5'in tam sayı kısmı 2'dir. (Dikkat! Eğer işlem 14 / 5 olsaydı 2.8'in tam sayı kısmı yine 2 olacaktı, tam sayılarla bölme işlemi yukarıya doğru yuvarlama yapmaz!) Dolayısıyla a/b = 12/5 = 2 olur. Yani, x = a/b-1 = 2-1 = 1 olur. y = a/b-2.0 = 2-2 = 0 olur.
real(a)/b ifadesinde a'yı reel yaptığımız için sonuç da reel olacaktır, yani 12.0 / 5 = 2.4 olur. Yani, z = real(a)/b + 1 = 2.4 + 1 = 3.4 olur. Formatta, yazacaklarımızın 1 basamak ondalıkla 3 karakter yer işgal etmesini istiyoruz. Dolayısıyla ekrana 1.0 0.0 3.4 yazılır.
8. (9 puan) Aşağıdaki Fortran90 programı derlenip çalıştırıldığında ekrana ne yazar? program hangisi character (len=10) :: sonuc logical :: a=.false.,b=.true. if (a.and.b) then sonuc = 'dogru' print *, 'Merhaba' end if if (.not.b) then sonuc = 'yanlis' print *, 'Selamlar' end if select case (sonuc) case('dogru') print *, '1' case('yanlis') print *, '2' case default print *, '3' end select end program hangisi a false, b true olarak tanımlanmış (logical değişkenler). Dolayısıyla a.and.b (a ve b) FALSE verir. Yani ilk if blokuna program hiç girmez..not.b (b değil), b true olarak tanımlandığı için yine FALSE verir. Dolayısıyla ikinci if bloku da hiç çalıştırılmaz. Yani, Merhaba veya Selamlar yazılmaz. Ayrıca sonuc değişkeni herhangi bir değer almaz. Select blokunda, sonuc 'doğru' oldugunda ekrana 1, 'yanlis' olduğunda '2' yazılsın deniyor. Fakat sonuc değişkeni her iki değeri de almadı. Dolayısıyla case default geçerlidir. Ekrana sadece 3 yazılır. Cevap: 3
9. (10 puan) Aşağıda verilen Fortran90 kaynak kodunun ana program kısmında boş bırakılmış yerlerden uygun olanlara, sadece GEREKEN altprogramları çağıran ifadeler ekleyerek; program derlenip çalıştırıldığında ekrana Şimdi 3 Şimdi 5 Şimdi 7 yazmasını sağlayınız. Bir altprogramı en fazla 2 satırda kullanabilirsiniz. program cagir integer :: i=1 call b(i) do while(i<8) call c(i) call b(i) end program cagir subroutine a(x) integer :: x x=x+1 end subroutine a subroutine b(y) integer :: y y=y+2 end subroutine b subroutine c(z) integer :: z print *, 'Şimdi ',z end subroutine c
İlk önce subroutine'lerin ne yaptığına bakalım. a, aldığı argümana bir ekler. b, aldığı argümana iki ekler. c ise aldığı argümanı Şimdi'nin yanına ekrana yazar. Eğer b'yi i ile çağırırsam ( call b(i) ), i'nin ana programdaki mevcut değeri 2 artacaktır. Dolayısıyla i'nin değeri do döngüsüne girmeden 3 olmuş olur (başta 1 idi). Do döngüsüne girince call c(i) dersem c subroutine'ine 3 değeri gider, dolayısıyla ekrana Şimdi 3 yazılır. Daha sonra döngüde tekrar call b(i) deyip i'yi 2 arttırım ve 5 yaparım. Bundan sonra döngünün başına dönülür. i hala 8'den küçük olduğu için döngü devam eder ve call c(i) Ekrana Şimdi 5 yazar. Sonra i'nin değeri call b(i) ile 7 olur. Döngünün başına tekrar dönülür, ekrana Şimdi 7 yazılır ve i 9 yapılır. Döngünün başına dönüldüğünde i artık 8'den küçük olmadığı için döngüden çıkılır ve program biter. DİKKAT: Hiçbir subroutine'i, ana programda tanımlanmamış argümanlarla çağıramazsınız! Örneğin call a(x) veya call b(y) yanlış ifadelerdir! x ve y ana programda tanımlı değildir! DİKKAT: do while döngülerinde kontrol değişkeni (burada i) otomatik olarak ARTMAZ. Sadece sayaçlı döngülerde (do i=m, n gibi) her devirde otomatik olarak artar. 10. (10 puan) Aşağıdaki Fortran90 programı derlenip çalıştırıldığında ekrana ne yazar? program cik integer :: i,j a: do i=1,25 if (i<24) cycle a j=1 b: do print *, i*j if (j>1) exit b j=j+1 b a end program cik
a döngüsünde, i 24'ten küçük olduğu sürece ilk satırdaki ifade bizi döngünün başına döndürür (cycle a). i=24 iken a döngüsüne girilir ve j=1 olur. b döngüsüne girilir, i*j 24*1 olduğundan ekrana 24 yazılır. if (j>1) exit b satırına geldik. Eğer j 1'den büyükse b döngüsünden çıkacak. j halen 1 olduğundan b döngüsünden çıkılmaz, sonraki satırda j 1 artar ve 2 olur. b döngüsünün başına dönülür. Şimdi i hala 24 ve j=2, dolayısıyla ekrana 48 yazılır. if (j>1) exit b satırına tekrar geldik. J artık 2 olduğu için b döngüsünden çıkılır, devam edilince de a döngüsünün başına gelinir. Şimdi i=25 oldu. Yukarıdakilerin aynısı I = 25 iken olunca bu sefer ekrana 25 ve 50 yazılır. Cevap: 24 48 25 50