Standart C Programlama Dili


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 F(4)), ancak F fonksiyonu içinde argümanın değerinin 5 yapıldığını varsayın. Bundan sonra, program içindeki 4 değişmezinin 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.