Nedir bu Reqursive(Özyinelemeli fonksiyon) , ne işe yarar, nerede kullanabiliriz ?

// 15 Mayıs 2009 // Delphi, Programlama

Reqursive fonksiyon kendi kendisini çağıran fonksiyonlara verilen genel addır. Alt alta hiyerarşik yapılarda yada içinden çıkılması zor bazı matematiksel hesaplamalarda çok kullanışlı bir yapıdır.Örneğin en bilinen örneği faktoriyel hesabıdır.Bilindiği üzere faktöriyel hesabı birbirini takip eden sayıların çarpımları ile yapılmaktadır ve ünlem (!) işareti ile ifade edilir. Örneğin 3 faktöriyel (3!) = 1 * 2 * 3 = 6 dır.
5! = 1 * 2 * 3 * 4 * 5 = 120 dir. Gelin bu faktöriyel hesabını yapabilen bir fonksiyonun Delphi’de ne kadar kolay kodlanabildiğine hep beraber göz atalım.

function Factoriel(Value : Smallint) : Longint;
begin
  if Value <= 1
  then Result := 1
  else Result := Value * Factoriel(Value - 1);
end;

İlginç bir kullanım öyle değil mi ? Fonksiyonun çalışma prensibine bir göz atalım. Diyelim ki Factoriel(1) biçiminde çağırdınız o zaman fonksiyon 1 değerini döndürüyor ve fonksiyondan çıkıyor. Diyelim ki Factoriel(5) biçiminde çağırdınız o zaman fonksiyonumuz şu hali alıyor:

Result := 5 * Faktoriel(4). Delphi bu kod satırını gördüğünde bir önceki değeri Stack Segmentte saklayarak şöyle bir çağrım daha yapıyor: Result := 4 * Factoriel(3) ve nihayetinde bu fonksiyon size 120 değerini geri döndürüyor.Peki bunu gerçek programlama ortamında nerede kullanırız ki..Biz matematik profesörü değiliz, elelam de zaten hazır kütüphane falan yapmış faktöriyelinden tut trigonemetrik hesaplara kadar herbirşey var dediğinizi duyar gibiyim..Hımm biraz düşünelim…Acaba program yetkilendirmesinde bu yapıyı kullanamaz mıyız ? Nasıl yani.. Diyelim ki ana formumuz da bir adet Main Menü var ve bu menünün pek çok alt itemları onlarında alt itemları, onların da alt itemları vs. bu uzayıp gidiyor.Belli bir seviye yok..5000 tane alt alta menü olabilir peki biz bunu nasıl tarayacağız..Yada aynı şeyi bir TreeView içinde düşünebiliriz. cemaliozan arkadaşımın Batık Bankasında kullanması gerektiği gibi ;) Eee peki bunu nasıl yaparız ki:

procedure ReqursiveFind(Menu : TMenu);
var
	iCounter :     Integer;

procedure FindAllItems(Mx : TMenuItem);
var
	iSubCounter : Integer;
begin
	ShowMessage(Mx.Caption);

  for iSubCounter := 0 to Mx.Count - 1 do
  	FindAllItems(Mx[iSubCounter]);
end;

begin
 for iCounter := 0 to Menu.Items.Count - 1 do
 	FindAllItems(Menu.Items[iCounter]);
end;

İşte kod bu, denemesi sizden.Siz tabii bunu güvenlik amacı ile de kullanabilirsiniz.Benim ShowMessage ile o anda işlem yapılan MenuItem’ın başlığını göstermek yerine Tag değerini kontrol ederek belli kullanıcılar için bazı kontroller yapabilir ve MenuItem’ı gizleyip gösterme kararı alabilirsiniz. ;) Artı bir avantaj ise ReqursiveFind proceduresinin TMainMenu ve TPopupMenu gibi menü componentlerinin atasını parametre olarak almasıdır. Bu şu anlama geliyor. Sadece MainMenu değil aynı zamanda PopupMenu de geçebilirsiniz bu procedure parametre olarak.

Saygılar,sevgiler..

Yorum Yazın