4.2.1. Değer İle Çağrı
FORTRAN’da ve bazı diğer dillerde argümanlar
referansla geçirilir. Yani, fonksiyona argümanın değeri yerine
adresi verilir. Bu yolla, çağrılan fonksiyon çağıran fonksiyon
tarafından argümanın saklandığı bölgeye erişir ve değerini değiştirebilir.
Böylece, bütün argümanlar hem fonksiyona bilgi iletirler, hem de fonksiyondan
bilgi geri getirirler, yani, istemesek bile, fonksiyona hem girdi hem de çıktı
için kullanılırlar. Eğer gerçek argüman, bir değişken değil de bir ifade veya
değişmez ise ne olur? Bu durumda, çağıran fonksiyon ifadeyi hesaplar, değerini
bir yerde saklar, sonra da bu adresi geçirir. Eğer çağrılan fonksiyon,
mantıksal olarak yapmaması gerektiği halde, argümanının değerini değiştirirse
(özellikle çok eski derleyicilerde)
bazı garip şeyler ortaya çıkabilir. Bir yordamın F
FORTRAN
fonksiyonunu bir değişmez olan 4
argümanı ile çağırdığını (yani
), ancak F(4)
F
fonksiyonu içinde
argümanın değerinin 5
yapıldığını varsayın. Bundan sonra, program
içindeki 4
değişmez
inin her kullanıldığı
yerde (örneğin
) PRINT *,4
4
’ün
5
olduğu gerçeği
ortaya çıkarılacaktır. Diğer bir
deyişle, yukarıdaki deyimden 5
elde edilecektir!
Yukarıdaki tartışma, argüman geçirilmesi için başka bir yöntemin gerekli olduğunu ortaya çıkarmaktadır. Bu değer ile çağrıdır ve C tarafından desteklenmektedir. Bu durumda, argümanın adresi yerine değeri fonksiyona geçirilir. Bu değer, özel bir bölgede, tıpkı normal bir yerel değişken gibi saklanır. Biçimsel argümana (yani parametreye) yapılan her türlü değişiklik yerel kopyasında yapılacaktır ve çağıran fonksiyondaki argümanlara herhangi bir etkisi olmayacaktır.
Bazı diller argüman geçişinin her iki yöntemine de izin
verirler. Örneğin, Pascal’da, önüne var
anahtar sözcüğü yazılarak tanımlanan parametreler için referansla çağrı
yapılır, var
yoksa değerle çağrı
yapılır. Normalde C değerle çağrıyı desteklediği halde, daha ileride
göreceğimiz gibi, mantıklı bir adres ve gösterge kaynaşması ile referansla
çağrı yapılabilir. İlk önce değerle çağrıya bir örnek verelim:
int fakt (int n) { int i = n; while (--n) i *= n; return i; }
Burada, önce i
’ye n
atanır, daha sonra n
sıfır oluncaya kadar aşağı doğru sayılır,
her sefer i
yeni n
ile çarpılır. Gördüğünüz gibi
n
’nin değeri değişir, ancak çağıran
fonksiyon tarafından geçirilen gerçek argüman üzerinde bunun bir etkisi
yoktur. Örneğin,
sayi = 4; printf("%d! = %d\n", sayi, fakt(sayi));
deyimlerinden sonra sayi
’nın değeri
(0
değil) 4
olmaya devam edecektir.
fakt
’taki n
parametresinin i
gibi yerel bir değişken olduğuna dikkat edin.