ANA SAYFA    |    YAYINLAR    |    BİYOGRAFİ    |    KONUŞMALAR    |    HABERLER    |    DİĞER    |


Kitabin asil yazari
TEMEL PASCAL
newDüzenlemeler

 


Bölüm 6: Prosedürler ve Fonksiyonlar

Pascal dili içerisinde vurgulanması gereken diğer önemli bir konuda Rutinlerdir. Temel olarak bir dizi komuttan meydana gelen rutinlerin sadece kendilerine özgü olan isimlerini yazarak o rutin içerisindeki komut dizisini tekrar tekrar çalıştırabiliriz. Böylece aynı kodları programın değişik bölümlerinde tekrar tekrar yazmak zahmetinden kurtulmuş olduğumuz gibi kodda bir güncelleme yapılması gerektiğinde sadece rutin içerisinde değişiklik yapılır ve bu rutini kullanan her yer otomatik olark güncellenmiş olur. Bu açıdan bakıldığında rutinler bir encapsulation (gizlemek- bir kabuk içine almak, "Object Oriented prog. yapısına özgü bir terim") mekanizması oluştururlar. Bu konu ile ilgili örneklere Pascal daki rutinlerin yazım kurallarından bahsettikten sonra geçeceğim.

Pascal Dilinde Prosedürler ve Fonksiyonlar :

Pascal dilinde bir rutin iki değişik yapıda bulunabilir, Fonksiyonlar ve prosedürler. Teoride prosedür, bilgisayardan yapmasını istediğiniz bir dizi işlem anlamındadır. Fonksiyon ise geriye bir değer dönderen bir dizi hesaplamalardır. (örneğin parametre olarak verilen sayının karesini döndermesi gibi). Bu iki yapı arasındaki en belirgin fark Fonksiyon geriye bir değer dönderirken, prosedürün bunu yapmamasıdır. Bu iki rutinin yapısda bir yada daha fazla sayıda, belirtilen veri tipinde parametreleri alabilmesidir.

Ugulamada ise bu iki yapı arasındaki fark çok az sınırlıdır. Yani bir fonksiyonu prosedür gibi kullanıp geriye sadece işlemin gerçekleşip gerçekleşmediğini bildiren yada hata kodunu dönderen bir fonksiyon yzabilirsiniz. Aynı zamanda bir procedürüde kendisine verilen parametreleri kullanarak bir dizi işlemi gerçekleştirip bu parametreler aracılığı ile geriye değer dönderebilirsiniz. (Bu konulardaki örnekleri göreceğiz.)

İşte size bir prosedür ve aynı işi gerçekleştiren iki fonksiyonun nasıl yazılacağına dair örnek kod:

procedure Hello;
begin
  ShowMessage ('Merhaba dünya !');
end;

function Double (Value: Integer) : Integer;
begin
  Double := Value * 2;
end;

// Yada yukarıdaki fonksiyonun alternatifi
function Double2 (Value: Integer) : Integer;
begin
  Result := Value * 2;
end;

Geriye bir değer dönderirken fonksiyonun ismine atama yapmak yerine Result kelimesini kullanmak gittikçe popülarite kazanmakla beraber kodun okunabilirliğinide arttırmaktadır.

Bu rutinleri bir kere tanımladıktan sonra onları program içerisinde defalarca çağırabilirsiniz.

procedure TForm1.Button1Click (Sender: TObject);
begin
  Hello;
end;
 
procedure TForm1.Button2Click (Sender: TObject);
var
  X, Y: Integer;
begin
  X := Double (StrToInt (Edit1.Text));
  Y := Double (X);
  ShowMessage (IntToStr (Y));
end;

 

NOT: Yukarıdaki procedure ler isimlerinin başındaki Tform1 gibi ifadeleri şimdilik görmemezlikten gelin. Boş bir form üzerine iki button ve bir tanede editbox bileşeni yerleştirip butonların üzerine tasarım modunda clickleyin. Delphi sizin için gereken destek kodunu oluşturacaktır yapmanız gereken begin ve end ifadeleri arasına gerkeli kodu yazmak olacak.

Şimdi daha önceden bahsettiğim Encapsulation kavramının ne olduğuna geri dönelim. Double adındaki fonksiyonu çağırdığınızda bir parametre olarak verdiğiniz sayının iki katını geri alırsınız. Yani fonksiyon geriye parametre olarak verdiğiniz sayının iki katını geri dönderir. Bu esnada ne tür bir algoritma ile bu işlemin gerçekleştiğini bilmezsiniz. Yani Double adındaki fonksiyon içerisinde nasıl bir işlem uygulandığını bilmenize gerek yoktur. Fonksiyon bir şekilde size parametre olarak verdiğiniz sayının iki katını geri dönderir. Bunu yaparken Double = sayı * 2 şeklinde bir işlemde gerçekleştirmiş olabilir yada Double = Sayı + sayı şeklindede bu işi yapmış olabilir sizin bunu bilmenize gerek yoktur. İleride daha iyi bir algoritma bulduğunuzda yani bu işlemi gerçekleştiren daha iyi bir yöntem bulduğunuzda sadece fonksiyonun içerisindeki kodu değiştirirsiniz. Programın diğer kısımlarında bu fonksiyona yapılan çağrılar değişmeden kalır. Böylece bütün bir programı güncellemek yerine sadece fonksiyonun içerini değiştirmekle işinizi gerçekleştirirsiniz.

Örneğin yukarıdaki örnek kodu çalıştırp 1. Butona basdığınızda karşınıza içerisinde "Merhaba Dünya J !" yazan bir mesaj alırsınız. Diyelimki ileride bu mesaj hoşunuza gitmedi ve değiştirmek istediniz, Yapmanız gereken Hello adındaki prosedürün içerğini değiştirmek olacak. Yani Buton1 in onClick olayını değiştirmenize gerek yoktur. Yada bu prosedürü programın başka yerlerindede kullanıyorsanız oralardada değişiklik yapmanıza gerek yok. Sonuçta hepsi Hello adındaki prosedürün son halini yani sizin üzerinde değişiklik yapmış olduğunuz halini bulup çalıştıracaktır.

NOT: Delphi içerisinde mevcut bir fonksiyon yada prosedürü çağırdığınızda o rutinin kaç tane parametre aldığını ve bu parametrelerin ne tür veri tiplerini kabul ettiğini bilmeniz gerekir(yani integer yada string bir değermi alıyor). Bunun için Delphi editörü büyük kolaylıklar sağlar. Adına Fly-By denen ipuçları yardımı ile bir rutinin ne tür parametreler aldığını programı yazarken görebilirsiniz. Delphinin bu özelliğine Code Insight teknolojisinin bir bölümü olan Code Parameters denir.

 

Reference olarak Parametreler:

Pascal rutinlerine iki değişik şekilde parametre geçebilirsiniz Referans yada Value(değer). Parametrelerin value olarak geçilmesi varsayılan durumdur. Bu metodla parametreler Stack'e yazalır, rutin bu parametrelerin kopyalarını kullanarak işlemleri gerçeklerştirir, parametre olarak verilen orjinal değişkenlerde bir değişiklik yapılmaz. Parametrenin referans olarak geçilmesinde ise rutine geçilen parametrelerin orjinal değerleri kullanılır (kopyası değil) ve işlemler bu değerleri üzerinden gerçekleşir. Dolayısı ile bir değişiklik olduğunda parametre olarak verilen değişkenin içeriğide değişmiş olur.

Parametrelerin referans olarak geçilmesi daha hızlı programlar demektir çünkü kopyalama işlemi yapılmaz.

İşte size bir rutine parametrenin VAR kullanılarak nasıl referans geçildiğini gösteren örnek:

procedure DoubleTheValue (var Value: Integer);
begin
  Value := Value * 2;
end;

Yukarıdaki örnektekteki prosedür bir fonksiyon gibi kullanılmıştır. Parametre olarak verilen Value değişkeni hem prosedüre bir değer girmekte hemde üretilen sonucu prosedür bitiminde içerisinde bulundurmaktadır.

var
  X: Integer;
begin
  X := 10;
  DoubleTheValue (X);

 

Yukarıdaki kodda DobleTheValue prosedürü çağırılmadan önce X in değeri 10 iken prosedür çağırıldıktan sonra X in değerinin 20 olduğunu görceksiniz. İşte parametrelerin referans olarak geçilmesini en iyi özetleyen örnekte bu idi.

Rutinlere parametre olarak nesnelerin verilmesi pek sık karşılaşılan bir durum değildir fakat yapılabilir. Nesneler zaten referans iken parametreye referans olarak geçilmesinin anlamı şudur "referansa referans".

Delphi3 ile gelen bir diğer parametre türüde OUT dur Com teknolojisi içerisinde kullanılır bu parametre ilk başta herhangi bir değer bulundurmazken dış dünya ile bağlantı kurmak için bu parametre aracılığı ile değer dönderir.

SABİT PARAMETRELER :

Parametrelerin referans olarak geilmesine alternatif olarak sabit parametre geçişi sunulur. Sabit bir parametreye rutin içerisinde bir atama yapamadığınız gibi derleyici bir takım optimizasyonlarda gerçekleştirir. Derleyici const parametresini bir referans gibi rutine geçebileceği gibi bu değer üzerinde bir değişiklik yapılmasınada izin vermez böylece kopyalama işlemleri olmadığı için daha hızlı bir program yazılmış olur. Aşağıdaki anlamsız kodu yazdığınızda Delphi size bir hata mesajı üretir :


function DoubleTheValue (const Value: Integer): Integer;
begin
  Value := Value * 2;      // Derleyici bu noktada hata verir
  Result := Value;	          // Çünkü sabit bir parametrenin içeriği       
				   // değiştirilmekisteniyor
end;

 

Open Array Parametreler (Açık dizi parametreler)

C Programlama dilinin aksine pascal rutinleri her zaman için sabit sayıda parametre alırlar. Her halükarda rutinlere değişken sayıda parametre geçmenin you vardır oda açık dizi kullanılarak yapılır. Bu işlem için rutine parametre olarak bir veri tipi belirli fakat kaç elemanlı olduğu belirsizbir array geçilir.


function Sum (const A: array of Integer): Integer;
var
  I: Integer;
begin
  Result := 0;
  for I := Low(A) to High(A) do
    Result := Result + A[I];
end;

 

Yukarıdaki örnekte High fonksiyonunu kullanarak dizinin kaç elemanlı olduğunu öğrenebiliriz ve kendisine parametre olarak verilen tamsayılar dizisinin elemanlarını toplayarak sonucu geri döndeririz. Bu fonksiyonun kullanımına örnek olarak aşağıdaki komututu kullanabiliriz :


X := Sum ([10, Y, 27*I]);

 

Eğer mevcut bir diziniz varsa bunuda parametre olarak geçebileceğiniz gibi slice() fonksiyonunu kullanarak mevcut dizinin sadece belirli bir bölümünüde parametre olarak geçebilirsiniz.


var
  List: array [1..10] of Integer;
  X, I: Integer;
begin
  // initialize the array
  for I := Low (List) to High (List) do
    List [I] := I * 2;
  // call
  X := Sum (List);

 

Slice() fonksiyonunun kullanımına örnek :


X := Sum (Slice (List, 5));

 

Bu bölümde gösterilen bütün örnek kod parçalarının derlenmiş halini OpenArr adındaki program içerisinde görebilirsiniz. Programdan bir çıktı olarak Şekil 6.1' bakabilirsiniz.

 

Type-Variant Open Array Parametreler (Değişken veri tipli açık dizi parametreler)

Bir önceki konuda açık dizileri işlerken parametre olarak geçilen değerlerin veri tiplerinin belirli bir yapıda olduğunu söylemiştik. Yani dizinin bütün elemanları ya integer tipte idi yada string yada benzeri diğer bir veri tipi. Bunun yanı sıra Delphide veri tipi heterojen olan dizilerde yaratmak ve bunları parametre olarak geçmekte mümkündür. Örneğin 7. Bölümde daha detaylı olarak göreceğimiz Format fonksiyonunda olduğu gibi :

function Format(const Format: string; const Args: array of const): string;

Bu fonksiyonun ikinci parametresi sayısı belirli olamayan açık bir diziden oluşmakta ve veri tipi olarakta belirli bir yapıya sahip değildir. Örneğin :


N := 20;
S := 'Total:';
Label1.Caption := Format ('Total: %d', [N]);
Label2.Caption := Format ('Int: %d, Float: %f', [N, 12.4]);
Label3.Caption := Format ('%s %d', [S, N * 2]);

 

Değişken veri tipli açık dizilerin elemanlarının heterojen bir yapıya sahip olduğunu söylemiştik peki Delphi bu elemanların hangi veri tipinde olduğunu nasıl anlıyor? Aslında bu elemanların her biri daha önceki bölümlerde bahsettiğimiz TVarRec Veri tipine sahip değerlerdir.

NOT: TVarRec veri tipi ile TVarData veri tipini birbiri ile karıştırmamak lazım. Aralarında önemli farklar bulunmaktadır. Nitekim TVarRec veri tipi Delphi ye özgü veri tipleri ile uyumlu iken (yani integer, string, double gibi değerleri alabilir) TVarData veri tipi OLE uyumlu veri tiplerini tutar. (Yani Windowsun panosuna kopyaladığınız bir Bitmap resimden tutunda Text bir dökümana kadar her türlü veri)

TVarRec veri tipi aşağıdaki yapıya sahiptir :

type
  TVarRec = record
    case Byte of
      vtInteger:    (VInteger: Integer; VType: Byte);
      vtBoolean:    (VBoolean: Boolean);
      vtChar:       (VChar: Char);
      vtExtended:   (VExtended: PExtended);
      vtString:     (VString: PShortString);
      vtPointer:    (VPointer: Pointer);
      vtPChar:      (VPChar: PChar);
      vtObject:     (VObject: TObject);
      vtClass:      (VClass: TClass);
      vtWideChar:   (VWideChar: WideChar);
      vtPWideChar:  (VPWideChar: PWideChar);
      vtAnsiString: (VAnsiString: Pointer);
      vtCurrency:   (VCurrency: PCurrency);
      vtVariant:    (VVariant: PVariant);
      vtInterface:  (VInterface: Pointer);
  end;

 

Bu veri tipinin alabileceği her record(kayıt) VType alanına sahiptir. Bu alan verinin tipini belirtmektedir.

Bu alanı kullanarak prosedürüme gönderilen farklı tipteki verileri toplamak istiyor olayım. SumAll adındaki fonksiyon bu alana bakıp verinin tipini belirliyor ve gerekli conversion (çevrim) işlemini yaparak toplama işlemini gerçekleştiriyor.


function SumAll (const Args: array of const): Extended;
var
  I: Integer;
begin
  Result := 0;
  for I := Low(Args) to High (Args) do
    case Args [I].VType of
      vtInteger: Result := Result + Args [I].VInteger;
      vtBoolean: if Args [I].VBoolean then Result := Result + 1;
      vtChar   : Result := Result + Ord (Args [I].VChar);
      vtExtended: Result := Result + Args [I].VExtended^;
      vtString, vtAnsiString:Result := Result + StrToIntDef ((Args [I].VString^), 0);
      vtWideChar: Result := Result + Ord (Args [I].VWideChar);
      vtCurrency:Result := Result + Args [I].VCurrency^;
    end; // case
end;

Ve OpenArr örneğine bu kodu ekleyerek biraz daha geliştirelim:


procedure TForm1.Button4Click(Sender: TObject);
var
  X: Extended;
  Y: Integer;
begin
  Y := 10;
  X := SumAll ([Y * Y, 'k', True, 10.34, '99999']);
  ShowMessage (Format (
    'SumAll ([Y*Y, ''k'', True, 10.34, ''99999'']) => %n', [X]));
end;

 

Şekil 6.2

 

Deplhi Çağrı Konvansiyonları

    Delphi 32 bitlik versiyonuyla FastCall adında yeni bir çağrı konvansiyonunuda getirdi. Fonksiyonun çalıştırılmasını hızlandırmak amacıyla mümkün olan noktalarda 3 parametreye kadar veriyi direkt olarak CPU'nun registerlarına geçmeyi sağlamaktadır. FastCall Convansiyonu register anahtar kelimesi kullanılarak yapılmaktadır. Buradaki problem varsayılan konvansiyon ve bunu kullanan fonksiyonların windows ile bire bir uyumlu olmayışıdır.Win32API fonksiyonları stdcall konvansiyonu kullanılarak ve orjinal pascalın Win16API konvansiyonu ile C programlama dilindeki CDECL çağrı konvansiyonunun karışımı ile yapılmalıdır.

Genelde FastCall convansiyonunu kullanmamak için bir sebep yoktur taki harici Windows çağrıları ve CallBack fonksiyonlarını kullanımına kadar. Bu bölümün sonlarına doğru StdCall konvansiyonu ile ilgili örnklerde yapacağız.

Metod nedir?

Daha önce Delphi ile ilgilendiyseniz metod kavramını duymuşsunuzdur. Metod, fonksiyon ve prosedür kavramlarının özel bir şeklidir. Delphide bir olayı ele alırken bu olayla ilgili bir metodu tanımlamamız gerekir, genel olarak prosedürü. Genelde metod kavramı bir sınıfa ait prosedür ve fonksiyonları belirtmek için kullanılır.

Bu noktaya kadar bir çok örnekte motodları kullandık. Örneğin aşağıdaki kod form üzerindeki butona tıklandığı zaman işletilmesini istediğimiz metodu göstermektedir. Bu metod Delphi tarafından otomatik olarak eklenmiştir.


procedure TForm1.Button1Click(Sender: TObject);
begin
  {here goes your code}
end;

 

Forward Declerations

Bir tanımlayıcı (identifier) yada benzerini kullanmak istediğinizde derleyici bu tanımlayıcının referans ettiği noktayı görmüş olmak ister. Bu sebeple bir rutini kullanmadan önce o rutinin bütün yapısını deklere etmiş olmanız gerekir.

Bazı durumlarda bu mümkün olmamaktadır. Örneğin A rutini içerisinden B'yi çağıracaksınız ve B'nin içerisindende A'yı. Böyle bir durumda A içerisinden B'yi çağırmak için B'nin önceden tanımlanmış olması gerekir bunun yanında B'den A'yı çağırmak içinde A'nın deklere edilmiş olması gerekir. (tavukmu yumurtadan, yumurtamı tavuktan? Hepside horozdanJ ). İşte bu karmaşayı çözmek için forward deklerasyonları kullanılır. Örneğin:

procedure Hello; forward;

 

Bu tanımlamadan sonra ileriki bir yerde kodun bütününün tanımlanmış olması gerekmektedir.


procedure DoubleHello; forward;

procedure Hello;
begin
  if MessageDlg ('İki mesajmı istiyorsunuz?',
      mtConfirmation, [mbYes, mbNo], 0) = mrYes then
    DoubleHello
  else
    ShowMessage ('Merhaba');
end;

procedure DoubleHello;
begin
  Hello;
  Hello;
end;

 

Bu yaklaşım size mutual (karşılıklı) recursion imkanını sağlar. DoubleHello, Hello'yu çağırırken Hello'da DoubleHello'yu çağırabilir.

Delphide forward decleration yapısı pek sık kullanılmasada ileriki bölümlerde daha detaylı inceleyeceğimiz UNITler aynı işlevi görmektedir. Bir unit'in interface kısmında fonksiyon yada prosedürün tanımlanması bir nevi forward deklerasyondur.

Aynı şeyler bir sınıf tipinin içerisinde metodların danımlanması içinde geçerlidir. Yani bu methodlarda bir nevi forward deklerasyonlardır.


type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  end;

 

Prosedür tipler:

Object Pascala özgü diğer bir tip ise prosedürlerdir. Bu konu gerçektende sadece birkaç programcının kullandığı ileri seviye programlama tekniklerini içerir. İleriki konularda daha detaylı incleyecek olmamıza rağmen burada bahsetmeninde faydasını görmekteyim.

Eğer sıradan bir programcı iseniz şimdilik bu kısmı atlayabilirsiniz. Pascalda prosedür tipler adında bir kavram bulunmaktadır, benzeri kavram C programlama dilinde fonksiyon işaretçileri olarak geçer. Örneğin Integer bir veri tipini parametre olarak alan procedür tipine referans vermek için :

type
  IntProc = procedure (var Num: Integer);

Bu prosedür tipi kendisiyle aynı yapıda parametre alan diğer rutinlerle özdeştir. Örneğin :

procedure DoubleTheValue (var Value: Integer);
begin
  Value := Value * 2;
end;

Prosedür tipleri iki farklı amaç için kullanabilirsiniz. Birincisi bu tipde değişkenler yaratmak için, ikincisi ise diğer rutinlere parametre geçmek için. Örneğin:

var
  IP: IntProc;
  X: Integer;
begin
  IP := DoubleTheValue;
  X := 5;
  IP (X);
end;

Yukarıdaki kod aşağıdaki ile aynıdır :


var
  X: Integer;
begin
  X := 5;
  DoubleTheValue (X);
end;

 

İlk kod ikincisine göre daha karmaşık olmasına rağmen neden gerekli? Bu tür bir tekniği isteğe göre frklı fonksiyonları çağırmak için kullanabiliriz.

Örnek olarak yeni bir proje başlatın ve iki tane radiobutton yerleştirin. Bu örnek iki temel prosedür üzerine kuruldu birincisi parametre olarak geçilen sayının iki katını alırken ikincisi üç katını almaktadır.

Şekil 6.3

procedure TripleTheValue (var Value: Integer);
begin
  Value := Value * 3;
  ShowMessage ('girilen değerin 3 katı: ' + IntToStr (Value));
end;

 

Kullanıcı her butona basışında radiobutonlarına bağlı olarak istenilen prosedür çağırılmaktadır nasılmı?

procedure TForm1.DoubleRadioButtonClick(Sender: TObject);
begin
  IP := DoubleTheValue;
end;

procedure TForm1.ApplyButtonClick(Sender: TObject);
begin
  IP (X);
end;

 

Yukarıdaki koddada gördüğünüz gibi IP adında integer bir değer alan prosedür tipi tanımlandı ve radiobutton lardan biri tıklandığında IP değişkeni daha önce deklere edilen iki fonksiyondan birini referens gösterir, böylece istenilen fonksiyon çağırılmış olunur.

IP ve X değişkenlerinin bütün prosedür ve fonksiyonlar tarafından görünebilmesi için form sınıf deklerasyonunun private sahasında deklere edilmesi gerekli. Bütün bunların ne anlama geldiği ileriki bölümde daha detaylı inclenecektir.


type
  TForm1 = class(TForm)
    ...
  private
    { Private declarations }
    IP: IntProc;
    X: Integer;
  end;

 

Fonksiyon Overloading (aşırı yükleme):

Daha önce yaptığım bir açıklamayı tekrarlamakta fayda görüyorum Fonksiyon Overloading konu başlığındada gördüğünüz gibi bazı kelimeleri Türkçeye çevirmediğim gibi bazılarınıda parantez içerisinde yazıyorum. Bu kelimeler bazen çevrimini yaptığım kelimelerden o kadar farklı anlamlara geliyorki bu sebeple böyle bir yöntem kullanmaktayım. Şu an bilgisayar terminolojisindeki (donanım ve yazılım olsun) kelimelerin Türkçe karşılıklarını bulmak için gönüllü guruplar çeşitli çalışmaları sürdürmektedir. Bu konuda kesin ve ortak bir dil oluşturulunca benimde sizinde işiniz bayağı kolaylaşacak.

Overloading fikri aslında çok basit temellere dayanmakta: Derleyici aynı ada sahip iki yada daha fazla fonksiyon tanımlamanıza imkan verir fakat bu fonksiyonların parametreleri farklıdır. Derleyici parametreyi kontrol ederek fonksiyonun hangi versiyonunu çağırmak istediğinizi tespit eder.

Aşağıdaki bir dizi fonksiyon tanımına göz atalım:


function Min (A,B: Integer): Integer; overload;
function Min (A,B: Int64): Int64; overload;
function Min (A,B: Single): Single; overload;
function Min (A,B: Double): Double; overload;
function Min (A,B: Extended): Extended; overload;

 

Örneğin Min(10,20) fonksiyonunu çağırdığınızda fonksiyon geriye integer değer dönderen versiyonunu seçerek işleminizi gerçekleştirir.

İki temel kural:

  • Fonksiyonların herbiri overload anahtar kelimesiyle bitmeli.
  • Aradaki farklılıklar parametrelerin tipleri yada sayılarında yada herikisinde olabilir. Geriye dönderilen değerin tipi aradaki farkın tepitinde kullanılmaz.

 

ShowMsg prosedürünün aşırı yüklenmiş üç değişik versiyonu şöyledir :

procedure ShowMsg (str: string); overload;
begin
  MessageDlg (str, mtInformation, [mbOK], 0);
end;

procedure ShowMsg (FormatStr: string;
  Params: array of const); overload;
begin
  MessageDlg (Format (FormatStr, Params),
    mtInformation, [mbOK], 0);
end;

procedure ShowMsg (I: Integer; Str: string); overload;
begin
  ShowMsg (IntToStr (I) + ' ' + Str);
end;

 

Bu üç değişik porsedürün kullanımı şöyledir :

ShowMsg ('Merhaba');
ShowMsg ('Toplam = %d.', [100]);
ShowMsg (10, 'MBytes');

Yukarıdaki ekran çıktısında bu kodun kullanımını görmektesiniz :

Daha önceden deklere edilmiş rutinleride overload edebilirsiniz.

Örneğin MessageDlg :

procedure MessageDlg (str: string); overload;
begin
  Dialogs.MessageDlg (str, mtInformation, [mbOK], 0);
end;

Varsayım olarak kullanılan parametreler:

Delphi4 ile birlikte gelen bu özelliği aşağıdaki örnek üzerinde inceleyelim. MessageBox metodunu encapsulate ederek yeni bir yapıya kavuşturalım:


procedure MessBox (Msg: string;
  Caption: string = 'Warning';
  Flags: LongInt = mb_OK or mb_IconHand);
begin
  Application.MessageBox (PChar (Msg),
    PChar (Caption), Flags);
end;

 

Yukarıdaki tanımı kullanarak aşağıdaki çağrıları yapabiliriz :


MessBox ('Hatalı olan bir şey var!');
MessBox ('Hatalı olan bir şey var!', 'Uyarı');
MessBox ('Merhaba', 'Mesaj', mb_OK);

 

Şekil6.5

Burada dikkat edilmesi gerekn bir nokta bulunmakta oda parametrelerden birinin geçilmesi. Yani ikinci parametreyi yazmadan üçüncüyü yazamazsınız aksi halde hata mesajı ile karşılaşırsınız.


MessBox ('Merhaba', mb_OK); // hata

Dikkat edilmesi gereken diğer noktalar ise:

  • Varsayılan değerlere sahip parametreler, parametrelerin deklerasyon sırası içinde en sonda yer almalı
  • Varsayım olarak verilecek değerler sabitlerden oluşmalı.
  • Varsayım değerler değer yada sabit olmalı.Var bildirimi ile referans olarak geçilemez.

 


© 1999 Mustafa Kasap. Tüm Hakları saklıdır.
 

Hosted by www.Geocities.ws

1