Pascal
PROCEDURE (Alt programlar)
Yazdığımız bir fonksiyon kendisine veri olarak bir veya birkaç parametre alıp sadece bir tek değer elde eder. Bu yüzden birkaç veri karşılığı sadece bir değer elde edeceğimiz durumlarda fonksiyon yazmak yararlı olabilir. Peki yazacağımız modülün birden fazla sonuç vermesi gerekiyorsa ne yapabiliriz? Bu noktada bize yardımcı olarak PROCEDURE'lar yani alt programlar devreye giriyor. Alt programlar sayesinde yazımızın başında da söylediğimiz gibi programımızı, ufak birçok modül yazıp bunları birleştirerek oluşturabiliyoruz. Modüllerimiz birçok parametre alıp birçok sonuç elde ederek sonuçları kendisini çağıran ifadeye iletebiliyor, bu sırada parametreleri tanımlama şeklinize göre veri parametrelerinin de değerleri değişikliğe uğrayabiliyor. İlk olarak yapısını görelim:
PROCEDURE procedure-ismi;
Bölgesel-bildirim-bölümü
BEĞİN
komutlar
END;
PROCEDURE kelimesinden sonra sizin vermiş olduğunuz isme göre modülümüz tanımlanmış olur.
Bölgesel-bildirim-bölümü'nde yer alan tüm değişkenler sadece modülümüz çalıştırıldığında tanımlıdırlar ve sadece modülün içinde kullanılabilirler.
Yazdığımız modülü çalıştırmak istediğimizde adını yazmamız yeterli olur. Eğer modülümüz parametrelere sahip olacaksa yapısı aşağıdaki gibi olmalıdır.
PROCEDURE proc-ismi (parametreler); Bildirim-bölgesi BEGIN komutlar END; Aynı şekilde isteğimize göre modülümüze isim vererek modülümüzü tanımlamış oluyoruz. Bundan sonra parantez içinde parametreler yer alıyor. Bildirim bölgesinde yer alanlar sadece modül çalıştırıldığında tanımlı oluyorlar. BEGIN...END arasında modülümüzü oluşturan komutlar yer alıyor. Modülümüzü çalıştırmak için modülün adını ve parantez içinde parametrelerini vermek yeterli olur. Parametrelere göre hacim hesaplayacak bir modül hazırlayalım:
PROCEDURE HACİM (UZUN-
LUK, GENİŞLİK, YÜKSEKLİK:
REAL);
VAR
H:REAL;
BEGÜN
H:- UZUNLUK*GENİŞLİK*
YÜKSEKLİK;
WRITELN (HACİM:0, H:9:1);
END;
Bir yapısı program veya fonksiyon yapısına benzer. Sadece ayrılmış kelime olarak PROGRAM veya FUNCTION yerine PROCEDURE kullanıyoruz. Ancak PROCEDURE başlığı FUNCTION başlığından bir noktada ayrılıyor: Procedure ismi bir değer yüklemede kullanılmadığından sonuç veri tipine ihtiyaç duymuyoruz. Yukarıda yazmış olduğumuz modülü çalıştıralım:
HACİM (10.0, 5.0, 4.0);
Elde edeceğimiz sonuç
HACİM:200.0
olurdu. Eğer bir modül olarak hazırlamak yerine HACİM modülünün yaptığını program içinde yaptırmak isteseydik, programımıza aşağıdaki satırları eklememiz gerekirdi:
UZUNLUK:
GENİŞLİK:
YÜKSEKLİK
ZUNLUK*GENİŞLİK*
YÜKSEKLİK;
WRITELN *', H;9:1);
Aslında modül yazarak bizim yaptığımız, bilgisayara yeni bir komut kazandırmaktır. Nasıl WRITE, WRITELN, READ vs. gibi komutlar varsa artık HACİM de bilgisayar için bir komut olmuştur. Programımızın neresinde hacim hesaplamamız gerekirse yeni komutun adını ve gerekli parametrelerini vermek yeterli olur.
Program Döküm Eki'nde PROCEDURE kullanarak çalışan basit bir program bulacaksınız.
Sadece değişken bildirimi ve program komutlarından oluşan uzun bir programı yazmanın ve anlamanın zorluğunu söylemeye gerek yok. Bu yüzden bir program haline getirmeye çalıştığımız problemimizi daha ufak parçalara bölmeye çalışırız. Ufak parçaları da daha ufak parçalara böleriz. Bu işlem bölünemeyecek ufak parçalara ulaşıncaya kadar devam eder. Bölünemeyecek ufak parçalar program modüllerimiz olan PROCEDURE halinde yazılırlar. Hemen hemen tüm problemleri veri okuma, hesap yazma, sonuçları basma şeklinde üç ayrı alt probleme bölebiliriz. Programımız bittiğinde bir grup modülden oluşur. Her modül daha fazla bölünemeyecek ufak problemlere karşılık gelir. Bir PASCAL procedure'ü, kendi ismi ile çağrılabilen bir program modüldür. Geçen bölümde genel olarak program modüllerini inceledik ve genel yapılarını gördük. Geçen bölümde gördüğümüz alt programlar sadece kendilerini çağıran programdan değer alabiliyor, ancak değer iletemiyorlardı. Daha doğrusu parametrelerde yer alan değişkenlerin değerini kullanıyorlar, ama bu değişkenlerin değerlerindeki değişiklik çağıran programı etkilemiyordu.
DEĞER VE DEĞİŞKEN PARAMETRELER
Geçen bölümde HACİM isimli bir modül tanımlamıştık. Modülümüz uzunluk, genişlik ve yükseklik değerlerini alıp cismin hacmini hesaplayarak ekrana yazıyordu. Bu modülü iki parçaya bölebiliriz. Yeni modülümüz gerekli bilgileri alsın ve parametre listesine ekleyeceğimiz dördüncü değişken yardımı ile bulduğu değeri ana programa göndersin.
Alt programlar sayesinde programımızı, ufak birçok modül yazıp bunları birleştirerek oluşturabiliyoruz.
PROGRAM HESAP;
VAR
UZUNLUK, GENİŞLİK
YÜKSEKLİK,SONUÇ : REAL;
PROCEDURE HACIM(U,G,Y:
REAL; VAR H:REAL);
BEGİN
EN
BEGİN
WRITEÇVERİLERİ
READ(UZUNLUK);
WHİLE UZUNLUK > 0.0 DO
BEGİN
READLN(GENISLIK,
HACIM(UZUNLUK,
GENİSLİK,YUKSEKLİK,SONUC);
WRITELNÇHACIM - *,
SONUC:9:3);
WRITELN;
GIRIN:”);
READ(UZUNLUK);
END;
END.
HACİM modülünde yer alan parametre listesindeki VAR sözcüğü dikkatinizi çekti mi? Geçen bölümde yer alan örnekte parametre listesinde yer alan değişkenleri sadece dışarıdan veri almakta kullanmıştık. VAR komutu sayesinde parametrelerde yer alan değişkenleri hem veri almada, hem de veri vermede kullanacağız. Sadece kendisini çağıran program, fonksiyon veya procedure'dan veri taşıyan parametre değişkenlerine DEĞER PARAMETRESİ diyoruz. Eğer parametrede yer alan değişken veya değişkenlerin önünde VAR komutu yer almış ise bu değişkenler hem değer almada hem de değer vermede kullanırlar. Bu tür değişkenlere DEĞİŞKEN PARAMETRE adını veriyoruz. Modülün çağrıldığı komutta DEĞER parametresine karşı gelen parametre bir değişken veya bir ifade olabilir. HACİM(UZUNLUK,... veya HACİM(2*UZUNLUK,...
Eğer DEĞİŞKEN PARAMETRE kullanmışsak modülün çağrıldığı komutta DEĞİŞKEN PARAMETRESİNE karşı gelen parametre sadece bir değişken olmalıdır. Değişken yerine bir ifade kullanmak hata mesajına yol açar. Yukarıdaki örneğimizde U, G, Y değişkenleri modülümüze modülü çağıran yerden veri taşınmasında kullanılıyor. H değişkeni ise modül için hesaplanan bir değeri modülü çağıran yere iletiyor. DEĞİŞKEN PARAMETRE'lerin bildirimi daima VAR (reserved word) komutu ile başlamalıdır. Eğer VAR komutunu yazmayı unutursanız bu değişkenler DEĞER PARAMETRESİ olarak alınırlar. Örneğimizdeki H := U * Y * G; komutu çalıştığında HACİM := U * Y * G; komutu çalışıyormuş etkisi olur. Ne zaman DEĞER PARAMETRESİ, ne zaman DEĞİŞKEN PARAMETRESİ kullanacağız? Başlıca üç kural şeklinde özetleyebiliriz: (1) Eğer modüle gönderilen bilgi geri alınmak zorunda değilse, o zaman DEĞER PARAMETRESİ kullanabiliriz. Bu tür bir parametreyi giriş parametresi olarak adlandırabiliriz.
(2) Eğer parametrede yer alan değişkenin değeri dışarı gönderilecekse bu değişken DEĞİŞKEN PARAMETRE tipinde olmalıdır. Bu tür bir parametreyi çıkış parametresi olarak adlandırabiliriz. (3) Eğer modüle gönderilen bilgi işlenerek geri gönderilecekse o zaman DEĞİŞKEN PARAMETRE kullanmak gerekir. Bu tür bir parametreyi giriş/çıkış parametresi olarak adlandırabiliriz. Bir DEĞİŞKEN parametresine karşılık gelen parametrenin sadece değişken olması gerektiğini, kesinlikle bir ifade veya sabit olmaması gerektiğini söylemiştik. Eğer değişkenin değeri değişirse bir ifadenin veya sabitin değişmesi gerekeceğinden bu çok saçma olurdu. Bu yüzden değişken parametrelerde sadece değişken kullanabiliyoruz.
PROCEDURE VERİ BÖLGESİ
Her modül çağrılışında, o modülün verilerini saklamak için hafızanın bir bölümü ayrılır. Bu bölgede modülde yer alan bölgesel değişkenler ve modülde bildirilecek sabitler için yer bulunur. Modülden çıkıldığında ayrılmış olan hafıza bölgesi silinir. Modül çağrıldığında ise bu bölge yeniden tanımlanır. Bu yüzden modül çağrıldığında modüle ait değişkenlerin değerleri tanımlanmamıştır.
PARAMETRE KURALLARI
Modülün çağrıldığı komutla, modülün başında yer alan parametre listesindeki değişkenler birbirine karşı gelir. (1) Her iki tarafta da aynı sayıda parametre olmalıdır. (2) Birbirine karşı gelen parametrelerin veri tipleri aynı olmak zorundadır. (3) DEĞİŞKEN PARAMETRE'ye karşı gelen parametre sadece değişken olmak zorundadır. DEĞER parametresine karşı gelen parametre değişken, sabit veya bir ifade olabilir.
İÇ İÇE MODÜLLER
Şimdiye kadar modüllerimizi ana programdan sonra tanımlamıştık. Gerçekten modüllerimiz de kendi başlarına ufak birer program olduklarından onlar da kendi içlerinde modüller tanımlayabilirler.
PROGRAM ICICE;
VAR
X,Y :REAL;
PROCEDURE DIS(VAR X
:REAL);
VAR
M,N :İNTEGER;
PROCEDURE IC(X :REAL);
VAR
N, O :İNTEGER;
BEGIN (* IC *)
END; (* IC *)
BEGIN (* DIS *)
END; (*1C*)
BEGİN (* DIS *)
END; (* DIS *)
PROCEDURE MINIMODUL;
CONST
BOSLUK
(* MINIMODUL *)
EN! (* MINIMODUL *)
BEGIN (* ICICE *)
END. (* ICICE *)
BLOK HER DEĞİŞKENİN ANLAMI
İÇ — modülünün parametresi) N,O (bölgesel değişkenler) İÇ (DIŞ modülünde tanımlanan modül) Y (İÇİÇE programında tanımlanmış değişken) DIŞ (İÇİÇE programında tanımlanmış modül) DIŞ — X (DIŞ modülünün parametresi) M,N (bölgesel değişkenler) İÇ (bölgesel modül) Y (İÇİÇE programında tanımlanmış değişken) DIŞ (İÇİÇE programında tanımlanmış modül) MİNİMODÜL BOŞLUK (bölgesel sabit) X,Y (genel değişkenler) DIŞ, MİNİMODÜL (İÇİÇE programında tanımlanmış modüller) İÇİÇE X, Y (genel değişkenler) DIŞ, MİNİMODÜL (İÇİÇE programında tanımlanmış olan modüller)
DEĞİŞKENLERİN ETKİ ALANI
Bir FUNCTION veya PROCEDURE başlığını izleyen tanımlamalar, bildirimler ve komutlar dizisine BLOK adını veriyoruz. Bir değişken sadece bildirilmiş olduğu blokta geçerlidir. Bu değişkeni sadece bildirilmiş olduğu blokta kullanabiliriz. Değişkeni içeren bloğun dışında bu değişkeni kullanmak anlamsız olur. Değişkeni kullanabildiğimiz program parçası değişkenin etki alanı içindedir. Bu durumda bir değişkenin etki alanı tanımlandığı bloğu içerir.
PROCEDURE HESAPYAZ; VAR
M:İNTEGER;
PROCEDURE HESAP;
VAR
SONUC 1: INTEGER;
BEGIN
END;
BEGİN
END;
Örneğimizde iki blok bulunuyor. İlk blok HESAPYAZ modülünün bildirimi ile başlıyor ve HESAP modülünü de kapsıyor. İkinci blok HESAP modülü ile başlıyor ve HESAPYAZ modülünün içinde kalıyor. HESAPYAZ modülünde bir tek M değişkeni tanımlandı. Bu değişken hem HESAP hem de HESAPYAZ modülünde kullanılabilir. SONUÇ ve I değişkenleri HESAP modülünde tanımlandılar ve sadece bu blok içinde kullanılabilirler. Başka bir deyişle, I veya SONUÇ değişkenlerini HESAPYAZ bloğunda kullanmanın bir anlamı yok.
Her iki değişken de bu bloğun her yerinde kullanılabilirler. Bu bloğun dışında, ana program da dahil hiçbir yerde kullanılamazlar. PROCEDURE ve FUNCTION'ların yapıları blok halinde olduklarından bunlar kendi içlerinde PROCEDURE veya blokları içerebilirler. İÇİÇE, DIŞ, İÇ, MİNİMODÜL bloklarından oluşan örneğimizi inceleyelim. Bu örnekte içiçe modülleri görmüştük.
Ana programı oluşturan İÇİÇE bloğunda tanımlanmış olan X ve Y değişkenleri tüm bloklarda kullanılabilirler. M ve N değişkenleri, DIŞ bloğunda tanımlanmasına rağmen hem DIŞ bloğunda hem de İÇ bloğunda kullanılabilirler, çünkü DIŞ bloğunu da içermektedir. N ve O değişkenleri sadece İÇ bloğunda kullanılabilirler. BOŞLUK sabiti ise sadece MİNİMODÜL bloğunda kullanılabilir. Bir PROCEDURE veya FUNCTION ismi, içinde bulunduğu blokta tanımlanmış olarak kabul edilir. Fakat bu modüller içinde bulunan yöresel değişkenler ve PARAMETRE değişkenleri yeni yapılmış olan modülde tanımlanmış olurlar. Bunu bir örnekle görelim:
FUNCTİON E(K,I,İ:İNTEGER):
İNTEGER;
P, M, N
BEĞİN
END;
F, bu fonksiyonu kapsayan blokta tanımlanmıştır. Ancak I, J, K, M, N ve P değişkenleri F bloğunda tanımlanmışlardır.
DEĞİŞKENLERİN ÇOKLU TANIMLANMALARI
Aynı isme sahip bir değişken farklı bloklarda tanımlanabilir. Mesela X bir değişken sadece bildirildiği blokta geçerlidir. Bu değişkeni sadece bildirildiği blokta kullanabilirsiniz.
X değişkeni İÇİÇE programında genel olarak tanımlanırken DIŞ ve İÇ modüllerinde de PARAMETRE değişkeni olarak tanımlandı. Programda X değişkeni kullanıldığında hangi tanımlamanın öncelik taşıyacağını merak edebilirsiniz. PASCAL'da bu durumlar için bir kural oluşturulmuş: Programın belirli bir yerinde aynı isme sahip değişkenler tanımlı ise, o zaman en ufak alana sahip değişken geçerli olur. Bizim örneğimizde İÇ modülünde X değişkeni kullanılırsa bu X değişkeni İÇ modülünde tanımlanmış olan değişkendir. PROCEDURE veya isimleri de birer belirteç olduklarından, bunlar için de Değişkenlerin Etki Alanı Kuralı'nı uygulayabiliriz. DIŞ modülü ana programda tanımlandığı için her yerde çağrılabilir. İÇ modülü DIŞ modülünün içinde tanımlandığından sadece kendisi veya DIŞ modül tarafından çağrılabilir. Mesela MİNİMODÜL bloğunda İÇ modülünü kullanmayı denersek SYNTAX ERROR ile karşılaşırız. Bunun sebebi bir belirteç kullanılmadan evvel tanımlanmasıdır. Görmüş olduğumuz gibi farklı bloklarda kullanıldığı sürece PASCAL, aynı isimde değişken, sabit veya belirteç kullanmamıza izin verir. Fakat PASCAL izin veriyor diye tüm bloklarda değişkenlere aynı isimleri vermek hiç de doğru değildir. Farklı isimler torbaya girmediğinden tüm değişkenlere aynı ismi vermek yerine her birine farklı farklı isimler vermek yerinde olacaktır.
PASCAL için modüler bir programlama dili demiştik. Modüler bir programlama dili olduğu için de, aynı anda farklı farklı programcılar bir programın farklı modüllerini hazırlayabilirler. Bu arada birbirlerinden habersiz olarak farklı değişkenlere aynı ismi verebilirler. Bu gibi durumlar için PASCAL hangi değişkenin kullanılacağını belirler. Bu sayede aynı anda farklı programcılar bir karışıklık çıkmadan programın farklı modüllerini hazırlayabilirler.
GENEL DEĞİŞKENLER
Bir FUNCTION veya PROCEDURE'da tanımlanan değişkenlerin o PROCEDURE veya FUNCTION'a ait bölgesel değişkenler olduğunu söylemiştik.
Bir FUNCTION veya PROCEDURE içinde tanımlanmamış, ancak bunlar tarafından kullanılabilen değişkenlere de GENEL değişkenler demiştik. Genellikle bu tür değişkenler ana programda tanımlanırlar.
Bir FUNCTION veya PROCEDURE'da bulunan komutlar genel bir değişkeni eğer aynı isimde başka bir bölgesel değişken yoksa kullanabilirler. Bu komutlar genel değişkenlerin değerlerini kullanabildikleri gibi, bunlara yeni değerler de verebilirler.
Modüllerle ana program arasında veri alış-verişi için ikinci bir yol olarak genel değişkenleri kullanıyoruz. Bir modülü çağırmadan evvel modüle gönderilecek verileri genel değişkene yükleriz. Aynı genel değişkenlere modüle elde edilen veriler yüklenir. Bu şekilde, modülden çıkıldığında gerekli değerler ana programa iletilmiş olur. Bu uygulamanın sakıncalarına gelecek yazımızda değineceğiz.