bÖlÜm 1 : pascal'in tarihÇesi · web vieweğer subrange olarak 1..3 alrsak bu kümenin...

66
Önsöz Temel Pascal şu ana kadar basımı yapılmamış fakat internet'te online olarak yayınlanan bir kitabın cevirisidir. Bu çeviri bire bir olmayıp bazı ek bilgiler de sunulmuştur. Aslında bu kitap şu an Türkiye kitap piyasasında bulunan Delphi3-4 Uygulama Geliştirme Klavuzu nun bir ön eki sayılabilir. Orjinal kitabın yazarı Marco Cantu bu bilgileri temel bilgi olarak görmekte fakat Delphi 3 kitabının okuyucu kitlesinin uzman sayılabileceği düşüncesiyle kitabında ayrıntılı olarak yer vermemiştir. Kitabın çevirisini yapmamdaki amaç gerçekten mükemmel sayılacak bu kitabı Türk okuyucular ile buluşturmak ve bu tür girişimlere örnek olamsını sağlamak. Telif Hakları Kitaptaki bilgilerin kısmi yada bütününün herhangi bir şekilde kopyalanması, değiştirilmesi yasaktır. Yorum ve Eleştiri Bu çalışma hakkındaki yorum, öneri, eleştiri gibi düşüncelerinizi bildirmeniz daha kaliteli bir çalışmanın ortaya çıkmasında katkıda bulunacak ve yapmayı düşündüğüm diğer çalışmalara ışık tutacaktır. Şimdiden teşekkür ederim. Kitabin yapisi ve içindekiler Bölüm 1 : Pascal'in Tarihçesi Bölüm 2 : Pascal'da Kodlama Bölüm 3 : Tipler, Degiskenler, Sabitler (Types, Variables, Constants) Bölüm 4 : Kullanici tanimli data tipleri Bölüm 5 : Statements Bölüm 6 : Prosedürler ve Fonksiyonlar Bölüm 7 : String yapilarini kullanma Bölüm 8 : Memory ve Pointer kavramlari BÖLÜM 1 : PASCAL'IN TARIHÇESI Delphi'de kullanilan Object Pascal (Nesne yönelimli Pascal programlama dili), Borland firmasinin 1995 yilinda gelistirdigi görsel gelistirme ortami (Visual development environmet,VDE) ile ortaya çikmamistir. Sadece Borland Pascal ürünleri içerisinde zaten kullanilan Object Pascal dilinin gelistirilmesiyle meydana gelmistir. Fakat Borland firmasi Pascal dilini de bulmamistir, sadece zaten var olan bir dili gelistirip popülaritesini arttirmistir. Bu bölüm Pascal dilinin tarihçesi hakkinda oldugu için kisa tutulmustur.

Upload: others

Post on 12-Mar-2021

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Önsöz

Temel Pascal şu ana kadar basımı yapılmamış fakat internet'te online olarak yayınlanan bir kitabın cevirisidir. Bu çeviri bire bir olmayıp bazı ek bilgiler de sunulmuştur.

Aslında bu kitap şu an Türkiye kitap piyasasında bulunan Delphi3-4 Uygulama Geliştirme Klavuzu nun bir ön eki sayılabilir. Orjinal kitabın yazarı Marco Cantu bu bilgileri temel bilgi olarak görmekte fakat Delphi 3 kitabının okuyucu kitlesinin uzman sayılabileceği düşüncesiyle kitabında ayrıntılı olarak yer vermemiştir.

Kitabın çevirisini yapmamdaki amaç gerçekten mükemmel sayılacak bu kitabı Türk okuyucular ile buluşturmak ve bu tür girişimlere örnek olamsını sağlamak.

Telif Hakları

Kitaptaki bilgilerin kısmi yada bütününün herhangi bir şekilde kopyalanması, değiştirilmesi yasaktır.

Yorum ve Eleştiri

Bu çalışma hakkındaki yorum, öneri, eleştiri gibi düşüncelerinizi bildirmeniz daha kaliteli bir çalışmanın ortaya çıkmasında katkıda bulunacak ve yapmayı düşündüğüm diğer çalışmalara ışık tutacaktır. Şimdiden teşekkür ederim.

Kitabin yapisi ve içindekiler

Bölüm 1 : Pascal'in Tarihçesi Bölüm 2 : Pascal'da Kodlama Bölüm 3 : Tipler, Degiskenler, Sabitler (Types, Variables, Constants) Bölüm 4 : Kullanici tanimli data tipleri Bölüm 5 : Statements Bölüm 6 : Prosedürler ve Fonksiyonlar Bölüm 7 : String yapilarini kullanma Bölüm 8 : Memory ve Pointer kavramlari

BÖLÜM 1 : PASCAL'IN TARIHÇESI

Delphi'de kullanilan Object Pascal (Nesne yönelimli Pascal programlama dili), Borland firmasinin 1995 yilinda gelistirdigi görsel gelistirme ortami (Visual development environmet,VDE) ile ortaya çikmamistir. Sadece Borland Pascal ürünleri içerisinde zaten kullanilan Object Pascal dilinin gelistirilmesiyle meydana gelmistir. Fakat Borland firmasi Pascal dilini de bulmamistir, sadece zaten var olan bir dili gelistirip popülaritesini arttirmistir.

Bu bölüm Pascal dilinin tarihçesi hakkinda oldugu için kisa tutulmustur.

Wirth'in Pascal'i

Asil Pascal dili 70 li yillarin sonlarina dogru Isveç'li bir profesör olan Niklaus Wirth tarafindan dizayn edilmistir.

Pascal dizayn edildiginde birçok programlama dili mevcuttu fakat bunlardan : FORTRAN, C, Assembler, COBOL gibi çok küçük bir bölümü genis bir kullanici kitlesine sahipti. Pascal'in dizaynindaki anahtar fikir veri yapilarinin kuvvetli olusu, degiskenler için deklerasyon istiyor

Page 2: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

olmasi, ve yapisal program kontrol bloklarinin olusuydu. Ayrica programlama dili ögrenen ögrenciler içinde bir araç olamsi hedeflenmisti.

Turbo Pascal

Borland'in dünyaca ünlü Pascal derleyicisi, Turbo Pascal, 1985 tilinda duyuruldu. Turbo Pascal, kullanimdaki basitligi ve gücü sayesinde, zamaninin en çok satan derleyicisi ünvanina sahipti ve PC platformunda dilin popülaritesini arttirmisti.

Turbo Pascal beraberinde Bütünlesik Gelistirme Ortami ( Integrated Development Environment IDE)' nida getirmisti. Bu ortam araciligi ile program kodunu düzenleyebilir ( WordStar türü bir editör ile), derleyiciyi çalistirabilir, hatalari görebilir, ve bu hatalrin bulundugu satirlara geri dönebilirdiniz. Bütün bunlar simdi çok alisilmis, siradan seyler olarak geliyor, fakat eskiden editörü kapatip, Dos'a dönüp, komut satirindan derleyiciyi çalistirip, hatalari tesbit edip tekrar editörü açip o hatalarin bulundugu satirlari düzenlerdik.

Bütün bunlarin disinda Microsoft firmasi kendi Pascal derleyicisini yüzlerce dolara satarken, Borland firmasi Turbo Pascal'i 49 dolara satmaktaydi. Turbo Pascal'in (Borland firmasinin ürettigi derleyicinin) yillarca süren basarisi, Microsoft firmasinin ürettigi derleyiciden vazgeçmesiyle sonuçlandi.

Delphi içerisindeki Pascal

Turbo ve Borland Pascal derleyicilerinin, dilin gelismesini saglayan 9 degisik sürümünden sonra, Borland firmasi 1995 yilinda Pascal derleyicisinin görsel bir programlama dili halini almis versiyonu olan Delphi adindaki ürününü çikardi.

Delphi Pascal dilini bir çok yönüyle gelistirmistir, bunlardan en önemlisi Object Pascal türevlerinden farkli olan Object-Oriented (Nesneye Yönelimli Programlama) mantiginin yerlestirilmesi idi.

BÖLÜM 2 : Pascalda Kodlama

Pascal programlama dilinin komutlarina geçmeden önce Pascalda kodlama stilinin önemi hakkinda biraz bahsetmek istiyorum. Burada hedefledigim soru yazim kurallarinin yaninda program kodunu nasil yazarsininiz ? Bu sorunun bir tek cevabi yoktur, kisilerin sahsi kodlama stili degiskenlik gösterebilir. Bununla birlikte yorumlar, büyükharf kullanimi, bosluklar ve güzel yazim kurallari ile ilgili bir kaç prensibin oldugunu bilmekte fayda var. Genel olarak kodlama stiline verilen önemin sebebi baskasi tarafindan okundugunda rahat anlasilir olmasidir. Kodun anlasilir olmasinin temelindeki fikir birlikteliktir, her ne tür yazim stilini seçerseniz seçin parojenizin basindan sonuna asagidaki konulari bir bütün olarak gözetmeniz gerekir.

Yorumlar

Pascalda yorum cümleleri kivircik parantez yada parantezi takip eden yildiz ile çevrelenir. Delphi , C++ stili yorum cümlelerinide destekler

{Bu bir yorum cümelesi örnegidir} (* Baska bir örnek *) // Bu da C++ türü yorum cümlesidir satirin sonuna kadar geçerlidir.

Ilk yazilan örnek en çok kullanilan ve en kisa olanidir. Ikinci örnek daha çok Avrupada kullanilir çünkü Avrupa standadindaki klavyelerde kivircik parantez yoktur. Üçüncü örnek ise C++ dan

Page 3: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

ödünç alinmistir ve Delphinin 32 bit versiyonlari tarafindan desteklenir. Son örnekteki stil tek satirlik kisa yorumlar yazmak için kullanilir ve istenilmeyen kod parçalarinin basina koyularak yorum haline getirilebilir.

Delphinin yazim kurallari ile standardizasyon saglamak için kitabin geri kalan kisminda yorumlari italik olarak yazacagim.

Üç degisik tipte yorum cümlesi yazabilmenin getirisi yuvalanmis yorum cümleleri yazmaya olanak saglamasidir. Bir örnekle açiklayalim

{ ….. kod { yorumlar …………} ….. kod }

yukaridaki yorum cümlesi hatalidir çünkü ilk kivircik parantez açildiktan sonra bitisi gösteren ilk kivircik paranteze kadar olan kisim yorum cümlesi olarak sayilacak kalan kod ise sayilmayacaktir. Örnektede italik ve normal yazi stilile gösterilmistir. Bu kodun dogrusu Pascalin sagladigi genis kullanim perspektifi ile söyle olabilir

{…… kod // Bu yuvalanmis yorum cümlesi dogru olani …. Kod }

Eger kivircik parantezden hemen sonra $ isaretini yazarsaniz bu kod yorum cümlesi olmaktan çikar ve {$X+} gibi bir derleyici direktifi haline gelir.

Aslinda derleyici direktifleride birer yorum cümlesi sayilir, yani {$X+ buraya yorum cümesi yazin} gibi bir kodda herhangi bir hataya sebep olamazken hem yorum cümlesi hemde derleyici direktifi olarak kabul edilir.

Büyük harf kullanimi

Pascal derleyicisi ( diger derleyicilerden farkli olarak ) büyük küçük harf ayrimi yapmaz. Bu yüzden bir degisken ismi olarak kabul edecegimiz index, Index, INDEX, InDeX hep ayni anlama gelmektedir. Genelinde bu esnekligin olumlu yanlari vardir, zira büyük/küçük harf ayrimi gözeten derleyicilerde bu sebepten dolayi bir çok yazim hatasi alinmaktadir.

Büyük/küçük harf kullanimi ile ilgili tek bir istisna vardir oda C++Builder ile standardizasyonu saglamak için component paketi olustururken Register proceduru yaziminda R harfinin büyük yazilmasi gerekmektedir. Bunun haricinde Delphide küçük/Büyük harf ayrimi gözetilmemektedir.

Bunun yaninda anlasilmasi zor bir kaç dezavantajlari bulunmaktadir. Ilk olarak, bu tanimlayicilarin ( degisken isimleri gibi) ayni oldugunun farkinda olmaniz gerekir, bu yüzden Index ve INDEX degisken isimlerini farkli birer yapiymis gibi kullanmamaniz gerekir. Eger çok uzun bir tenimlayici ismi belirleyecekseniz (arada bosluk olmamak kosulu ile) kelimelerin bas harflerini büyük harfler ile yazabilirsiniz.

BenimUzunDegiskenim BenimUzunVeAnlamsizSayilabilecekDegiskenim gibi

Program koduna eklemis oldugunuz bosluk, tab, bos satirlar derleyici tarafindan göz ardi edilir. Bütün bu elemanlar White Space’s olarak tanimlanir. White Spaceler kodun okunulabilirligini arttirmak için kullanilir, derleyici tarafindan dikkate alinmaz.

Page 4: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Basic programlama dilinin aksine Pascal tek bir kod parçasini birden fazla satira yazmaniza izin verir, uzun bir komutu bir yada daha fazla satira yazabilirsiniz. Bunun dezavantaji ( daha çok Basic dili kullanicilari için) bir komutun bittigini göstermek için sonuna noktali virgül konulmasinin gerekliligidir.

Tekrar belirtmek gerekirse, bosluklarin, birkaç satira dagilmis komutlarin kullanimi ile ilgili kesin kurallar olmamakla birlikte su maddelere dikkat etmek gerekir.

- Delphi editöründe 60-70 karakter yazdiktan sonra göreceginiz dikey bir çizgi vardir. Bu çizgiden itibaren yazmaya devam etmekten kaçinmak lazim bubun sebebi kodun yazicidan çiktisi alinirken kelimelerin ortadan bölünüp alt satira atilmis olamasi gibi sorunlar ile karsilasilabilecegidir.

- Eger prosedür veya fonksiyonlariniz birden fazla parametreden olusuyorsa bu parametreleri birden fazla satira dagitmak genel bir programlama teknigidir.

- Yorum cümlelerinden önce bos bir satir birakabileceginiz gibi uzun program komutlarinida aralarinda bos satirlar birakarak bölebilirsiniz bu hem okunabilirligi arttirir hemde yazicidan çikti aliminda karsilasilabilecek sorunlari azaltir.

- Bir fonksiyon çagrisi yaparken parametreler arasinda bosluklar birakmaya çalisin hatta açtiginiz parametreden sonrada bir bosluk birakin. Ve tabiki bir islemin operatörleri arasinada bosluk birakin. Biliyorumki bazi programcilar bu söylediklerime karsi çikacaklar fakat israrli olmama sebep nokta : Bosluk kullanimindan dolayi bir kaybinizin olmayisidir. (Biliyorumki bosluk kullanimi diskte yer kaplayacak ve modem araciligi ile yükleme islemi yapildiginda zaman kabina yol açacak ama bütün bunlar günümüzde önemsiz bir hale geldi.)

Güzel Yazim

White Space’lerin kullanimi ile ilgili yapilan son tavsiyeler aslinda Pascal dili formatinin tipik sitilidir ve güzel yazim olarak bilinir. Bu kural çok basittir: Her birlesik program komutu yazacaginiz zaman iki bosluk karateri içeriden yazmaya baslayin.

if …. then   Komut; if ….. then begin   Komut1   Komut2 end;

if …. Then begin   if … then     komut1;   komut2; end;

Yukaridaki format güzel yazim sitili temel alinarak olusturulmustur, kullanicilar kendi sitillerini kullanarakta ayni kodu yazabilirler.

Bu tür bir yazim sitili degiskenler yada veri yapilari içinde kullanilabilir.

type   Harfler = set of Char; var

Page 5: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

  Ad: string; begin   { yorum cümleleri }   MessageDlg ('Bu bir mesaj',     mtInformation, [mbOk], 0);

Tabiki, bu tür bir öneri baskalari tarafindan okunulabilirligi arttirmak amacini gütmektedir, derleyici bütün bu yazim formatini gözardi edecektir. Bu yazim sitilini kitabin geri kalan kisminda kullanacagim. Delphi’nin kaynak kodu, yardim dosyalari ve örnekleri benzeri bir yazim sitilini kullanmaktadir.

Syntax Highligting (Türkçeye çevirmedim, konuyu okuyunca anlasilacak)

Pascal kodunu daha kolay okunabilir ve yazilabilir hale getirmek için, Delphi editörünün “Color syntax highligting” adinda özelligi bulunmakta. Yazdiginiz kelimelerin Pascal dilindeki anlamlarina göre editörde farkli renklerde görünmesini saglar. Varsayilan deger olarak Keyword( anahtar kelimeler) ler kalin, karakter katarlari ve yorumlar renkli ( genelde italic) gibi yazilir.

Genelde ayrilmis kelimeler (Reseved words), yorumlar, ve karakter katarlari bu özellikten yararlanan üç elemandir. Ilk bakista yanlis yazilmis bir anahtar kelimeyi, dogru olarak tamamlanmamis karakter katarini, ve birden fazla satira dagilmis uzun yorum cümlelerini görebilirsiniz.

Environment Options dialog kutusundan editör colors (sekil 2.1) sayfasini kullanarak bu özellikleri kisisellestirebilirsiniz. Eger tek basiniza çalisiyorsaniz hoslandiginiz renkleri seçin. Birden fazla kisinin kullandigi bilgisayari kullaniyorsaniz standart renkleri kabul etmeniz gerekmektedir. Alisik oldugum bilgisayarin renk profili disindaki bir profili kullanan bilgisayarda çalismak bana çok zor geliyor.

Sekil 2.1 Color syntax highlighting ayarlarinin yapildigi iletisim kutusu

Page 6: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Kitaptaki program kodlarinda birçok syntax highlighting özelliklerini uyguladim. Umarim okunulabilirligi arttirmistir

Kod Sablonlarinin Kullanimi

Delphi 3 kaynak kodu yazimi için yeni bir özelligi beraberinde getirmistir. Ayni Pascal dili komutlarini tekrarli bir sekilde yazdigimiz için Boland kod sablonu adindaki bir özelligi sunmustur. Basitce kod sablonu kod parçasina yapilmis kisaltmadir. Kisaltmayi yazarsiniz ve ardindan Ctrl-J tusuna basarsiniz asil kod parçasi sizin yerinize editöre yazilir. Mesela editörde arrayd kelimesini yazip Ctrl-J tusuna basarsaniz editör bu kelimeyi siler ve yerine sunu yazar:

Array [0..] of ;

Kod sablonlarinin birden fazla çesidi oldugu için, eger kisaltmanin sadece bir kaç harfini yazip Ctrl-J tusuna basarsaniz, editör size o harler ile baslayan kod sablonlarinin listesini açilir bir yerel listede sunar. (Sekil 2.2)

Sekil 2.2 : Kod sablonu seçimi

Kod sablonlarini, var olanlari degstirerek yada yenilerini ekleyerek kisisellestirebilirsiniz. Öger böyle bir seye girisecekseniz aklinizda bulundurmaniz gereken genellikle kod sablonlarinin ‘|’ karakterini içeriyor olmasidir. Bu karakterin amaci siz kisayolu yazip Ctrl-J tusuna bastiktan sonra kursörün nereye gitmesini belirtmesidir.

Language Statements

Birkaç tanimlayici (identifier) tanimladiginizda bunlari komutlarin içerisinde kullanabilirsiniz. Pascal birden fazla komutlar ve ifadeler kümesi sunar. Ilk olarak Keywords (anahtar kelimeler), Expressions ( ifadeler) ve Operatörlere göz atalim.

Keywords

Keyword’ler Object Pascalin arilmis kelimeleridir ( Reserved Words). Yani Keyword kategorisi altinda toplanan kelimeler dilin kendi kullanimi için sunulmustur. Delphi nin yardim dosyalarinda söyle geçer ayrilmis kelimeler birer tanimlayici olarak kullanilamazlar.

Iste size Object Pascal dilinde özel bir yere sahip olan ayrilmis kelimeler (Delphi 4 den alinmistir)

Page 7: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Keyword Roleabsolute directive (variables)abstract directive (method)and operator (boolean)array typeas operator (RTTI)asm statementassembler backward compatibility (asm)at statement (exceptions)automated access specifier (class)begin block markercase statementcdecl function calling conventionclass typeconst declaration or directive (parameters)constructor special methodcontains operator (set)default directive (property)destructor special methoddispid dispinterface specifierdispinterface typediv operatordo statementdownto statement (for)dynamic directive (method)else statement (if or case)end block markerexcept statement (exceptions)export backward compatibility (class)exports declarationexternal directive (functions)far backward compatibility (class)file typefinalization unit structurefinally statement (exceptions)for statementforward function directivefunction declarationgoto statement

Page 8: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

if statementimplementation unit structureimplements directive (property)in operator (set) - project strucureindex directive (dipinterface)inherited statementinitialization unit structureinline backward compatibility (see asm)interface typeis operator (RTTI)label declarationlibrary program structuremessage directive (method)mod operator (math)name directive (function)near backward compatibility (class)nil valuenodefault directive (property)not operator (boolean)object backward compatibility (class)of statement (case)on statement (exceptions)or operator (boolean)out directive (parameters)overload function directiveoverride function directivepackage program structure (package)packed directive (record)pascal function calling conventionprivate access specifier (class)procedure declarationprogram program structureproperty declarationprotected access specifier (class)public access specifier (class)published access specifier (class)raise statement (exceptions)read property specifierreadonly dispatch interface specifier

Page 9: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

record typeregister function calling conventionreintroduce function directiverepeat statementrequires program structure (package)resident directive (functions)resourcestring typesafecall function calling conventionset typeshl operator (math)shr operator (math)stdcall function calling conventionstored directive (property)string typethen statement (if)threadvar declarationto statement (for)try statement (exceptions)type declarationunit unit structureuntil statementuses unit structurevar declarationvirtual directive (method)while statementwith statementwrite property specifierwriteonly dispatch interface specifierxor operator (boolean)

Ifadeler ve Operatörler

Içerisinde kullanilan operatöre bagimli olan ifadeleri olusturmak için genel bir kural yoktur, ve Pascal dili bir çok operatöre sahiptir. Bunlar arasinda mantiksal, aritmetik, boolean(dogru/yanlis), iliskisel, ve küme operatörleri ile digerleri bulunmaktadir. Ifadeler bir degiskene deger atamak için, fonksiyon yada prosedürün parametrelerinin degerini belirlemek için, yada bir durumu test etmek için kullanilir. Ifadelerde fonksiyonlari içerebilir. Bir islem yaparken kullandiginiz operatörler ve tanimlayicilarin birlikteligine ifadeler diyoruz.

Ifadeler bir çok programlama dilinde ortaktir. Bir ifade geçerlilik arzeden sabitler, sayisal degerler, operatörler, ve fonksiyon sonuçlarindan olusabilir. Ifadeler bir fonksiyon yada prosedüre parametre olarak geçilebilir.

Page 10: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Operatörler ve Öncelikleri

Hayatinizda hiç program yazmamis olsanizda ifadenin ne oldugunu bilirsiniz. Burada Pascalin özel operatörleri üzerinde duracagim. Bu dile ait operatörleri önceliklerine göre siralanmis olarak Tablo 2.1 de bulabilirsiniz.

Diger bazi programlama dillerinin aksine and ve or operatörlerinin iliskisel operatörlere göre önceligi vardir. Bu yüzdendirki a

Bazi operatörler degisik veri yapilariyla kullanildiginda farkli anlamlar kazanirlar. Mesela, + operatörü iki sayiyi toplamak için kullanildigi gibi iki karakter katarini birlestirmek için, iki kümenin birlesimini almak için, ve dahasi pointera offset eklemek içinde kullanilabilir. Öte yandan C programlama dilinde oldugu gibi iki karakteri + operatörü ile ekleyemezsiniz.

Ilginç diger bir operatör ‘div’ dir. Pascalda herhangi iki sayiyi / operatörü ile bölebilirsiniz ( kayan noktali yada tamsayiyi ). Sonuç olarak reel bir sayi elde edersiniz. Eger iki tamsayi bölüp sonuç olarakta bir tamsayi elde etmek istiyorsaniz div komutunu kullanin.

Tabl0 2.1: Pascal Language Operators, Grouped by Precedence

Unary Operators (Highest Precedence)@ Address of the variable or function (returns a pointer)not Boolean or bitwise not

Multiplicative and Bitwise Operators* Arithmetic multiplication or set intersection/ Floating-point divisiondiv Integer divisionmod Modulus (the remainder of integer division)as Type-safe typecast (RTTI)and Boolean or bitwise andshl Bitwise left shiftshr Bitwise right shift

Additive Operators+ Arithmetic addition, set union, string concatenation, pointer offset addition- Arithmetic subtraction, set difference, pointer offset subtractionor Boolean or bitwise orxor Boolean or bitwise exclusive or

Relational and Comparison Operators (Lowest Precedence)= Test whether equal<> Test whether not equal

Page 11: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

< Test whether less than> Test whether greater than<= Test whether less than or equal to, or a subset of a set>= Test whether greater than or equal to, or a superset of a setin Test whether the item is a member of the setis Test whether object is type-compatible (another RTTI operator)

Küme Operatörleri

Küme operatörleri sunlardir (+)birlesim, (-)fark, (*)kesisim, (in) elemani olup olmadigini test etmek, ve diger iliskisel operatörler. Bir elemani kümeye eklemek için, küme ile elemanin birlesimini alabilirsiniz. Simdi de Delphide font sitilleri ile ilgili örneklere göz atalim.

Style := Style + [fsBold]; Style := Style + [fsBold, fsItalic] - [fsUnderline];

Standard olarak daha hizli olan Include ve Exclude prosedürlerinide kullanabilirsiniz.

Include (Style, fsBold);

Sonuç

Simdi Pascal programlarinin temel yapisini ögrenmis bulunmaktayiz ve detaylarini anlamak için haziriz. Ise kullanici tanimli ve önceden tanimli veri yapilarini incelemkle baslayacagiz. Daha sonra anahtar kelimeleri (Keywords) kullanarak program komutlari olusturmaya baslayacagiz.

BÖLÜM 3 : Tipler, Degiskenler ve Sabitler

Orjinal Pascal dili, su an programlama dillerinde ortak olarak kullanilan temel yapilar üzerine kurulmustur. Bu yapilardan ilki data tipleridir. Tip bir degiskenin alabilecegi deger araligi ile o degisken üzerinde uygulanabilecek islemleri belirler. Pascaldaki veri tipi kavrami, aritmetik veri tiplerinin degisken sekilde kullanildigi C’den, ve BASIC dilinin orjinal versiyonundan çok daha güçlüdür.

Degiskenler :

Pascal dili degiskenlerin program içerisinde kullanilmadan önce tanimlanmis olmasini sart kosar. Degisken tanimi yaptiginiz zaman bu degiskenin tipinide belirtmek zorundasinizdir. Iste bir kaç örnek degisken tanimi :

Var  value : integer;  IsCorrect : Boolean;  A, B : char;

Var anahtar kelimesini (KeyWord) kod içerisinde farkli yerlerde kullanabilirsiniz, örnegin procedure yada fonksiyon tanimlarinin basinda kullanildiginda tanimladiginiz degiskenler saece o procedure yada fonksiyon tanimi içerisinde geçerli olur. Yada bir Unit’in basinda tanimlayarak degiskenin programin heryerinden erisilebilir olmasini saglayabilirsiniz. Var kelimesinden sonra sirayla degiken ismi, ikinokta üstüste , degiskenin tipi ve noktali virgül ile tek bir degisken tanimi yapilmis olur bu sekilde bir degisken tanimi listeside olusturulabilir. Yukaridaki örnegin son satirinda oldugu gibi tek bir satirda birden fazla degisken tanimlayabilirsiniz.

Page 12: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Degiskeni ve tipini bir kere tanimladiktan sonra degisken üzerinde sadece o degisken için tanimlanmis olan islemleri gerçeklestirebilirsiniz. Örnegin boolean degeri test için, integer degeri ise numerik bir tanim içerisinde kullanabilirsiniz. C dilinde oldugu gibi Boolean ve Integer tiplerini birbirlerinin yerine kullanamazsiniz.

Tanimlamalari yaptiktan sonra asagidaki kodu yazabiliriz:

Value := 10;IsCorrect := true;

fakat asagidaki örnek yanlis olur çünkü degiskenlerin veri tipleri farklidir:

Value := IsCorrect; // Error

Eger yukaridaki kodu derlemeye çalisirsaniz Delhi size söyle bir hata mesaji verecektir:Incompatible types: 'Integer' and 'Boolean'. Bu tür hatalar genellikle programlama hatalaridir çünkü boolean tipteki bir degeri integera aktamaya çalismak normal birsey degildir. Delphi yi bu tür bir hata verdigi için suçlayamazsiniz çünkü o sizi sadece kodda bir yanlislik olduguna dair uyarmaktadir.

Bir degiskenin degerini bir tipten digerine çevirmek elbette mümkündür. Bazi durumlarda bu çeviri isi otomatik olarak yapilir, bazi durumlardada sizin sistem fonksiyonlarini çagirarak yapmaniz gerekir.

Delphide global bir degiskene ilk degeri onu tanimlarken atayabilirsiniz. Söyleki :

var  Value: Integer = 10;  Correct: Boolean = True;

Sabitler:

Pascal programin isleyisi sirasinda degistirilemeyen sabit degerlere isimler atayabilmenize olanak verir. Bir sabit tanimlamak için tipini belirtmenize gerek yoktur fakat bir baslangiç degeri tanimlamaniz gerekir. Derleyici sabitin degerine bakip otomatik olarak bir tip atar.

Iste bir kaç örnek:

const    Bin = 1000;   Pi = 3.14;   Yazar = 'Mustafa Kasap';

Delphi sabitlerin data tiplerini degerlerine bakar kenidisi tanimlar. Yukaridaki örnekte Bin adindaki degiskenin tipi degerini tsiyabilecek en küçük integral tip olan SmallInt olarak tanimlanir. Eger Delphinin bu degisken için özel bir tip kullanmasini istiyorsaniz tanimini yaparken bildirmeniz gerekir: Örnegin:

Const   Bin : Integer = 1000;

Sabit tanimi yaptiginizda derleyicinin bu sabit tanimi için iki sekilde davranmasini saglayabilirsiniz. Birincisi sabit için bir bellek alani ayirir ve programin sonuna kadar orada saklar. Ikincisi gerçek degeri çogaltarak her kullanildigi yere kopyalamasi saglanabilir. Ikinci yaklasim basit sabit degerle için dogru olabilir.

Not : Delphinin 16-bitlik versiyonu programin çalisma esnasinda sabitlerin bir degisken gibideger degistirmesine izin vermektedir. Delphinin 32-bitlik versiyonuda $J derleyici direktifi kullanildiginda yada Delphi menülerindeki Project options dialog kutusundaki Compiler sayfasinda yer alan Assignable typed constant seçeneginin isaretlenmesi ilede bu islem gerçeklestirilebilir. Bu

Page 13: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

seçenek varsayim olarak isaretlidir fakat Genel bir programlama teknigi olarak bu hileyi kullanmamanizi öneririm. Sabite yeni bir deger atayarak derleyicinin bu sabit üzerinde yapacagi tüm optimizasyonlari engellemis olursunuz. Böyle bir durumda sabit yerine degisken tanimlayiniz.

Kaynak Karakter dizisi Sabitleri

const   Yazar = 'Mustafa Kasap';

Sabit bir Karakter dizisi tanimlarken yukaridaki gibi bir tanim yapacaginiza Delphi 3 ile birlikte su tanimi yapabilirsiniz :

resourcestring   Yazar = 'Mustafa Kasap';

Her iki durumdada programin isleyisi esnasinda degismeyecek bir sabit tanimliyorsunuz. Aradaki fark sadece bildirimleri. ResourceString direktifi ile sabit tanimlarken sabitin program kaynaklarinda yer almasini yani bir karakter dizisi tablosunda yer almasini saglarsiniz.

Delphinin bu yetenegini görmek için üzerinde bir button bileseni bulunan asagidaki ResStr örnegini inceleyelim:

resourcestring   Yazarismi = 'Mustafa Kasap';   Kitapismi = 'Temel Pascal';

procedure TForm1.Button1Click(Sender: TObject);beginShowMessage (Kitapismi + #13 + Yazarismi);end;

Yukaridaki örnegin çiktisi iki satirdan olusur bunun sebebi iki tane karakter dizisini NewLine karakteri ile ayirmis olmamizdir. ( #13 yeni bir satira baslama karakteridir )

Bu programi ilginç kilan nedir? Basit gibi görünsede anlamak için yapmaniz gereken su Delphi ile birlikte gelen Resource Explorer programini çalistirip incelemek. Göreceksinizki tanimladiginiz degiskenler program kodunuzla birlikte derlenmiyor fakat program kodunuzun farkli bir alaninda yer aliyor !!!

NOT : Kisaca ResourceString lerin avataji bellegin daha etkili kullaniminin saglanmasi ve Bu karakter dizilerini yerellestirebilmektir. (Yani program kodundan bagimsiz olarak bu karakter dizilerini farkli bir dile çevirebilirsiniz.)

Veri Tipleri:

Delphide, üç guruba ayirabilecegimiz önceden tanimli veri tipleri bulunmaktadir. Bunalar: Ordinal tipler, Gerçel tipler ve karakter dizileridir: (Ordinal Types, Real Types and String Types). Ordinal ve Gerçel tipleri bu bölümde inceleyecegiz, Karakter dizilerini ise bir sonraki bölümde. Ayrica bu bölümde Delphi kütüphanelerinde tanimlanmis tiplerdende bahsedecegim, bu tipler derleyici tarafindan önceden tanimlanmis olmamasina ragmen öyle düsünülebilir.

Ayrica Delphide Tipsiz veri tipleride bulunmaktadir. Bunlar Variant olarak tanimlanir ve degisken veri tiplerini barindirabilir. Bu kitapta, degisken veri tipi hakkinda bilgi verilmeyecektir. Özet olarak Variant veri tipi, tipi olmayan bir veri tipidir. (Ne açiklama ama).

Ordinal Tipler:

Page 14: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Ordinal tipler düzen ve sira kavramini temel alir. Bu veri tipi ile iki degiskenden hangisinin büyük oldugunu sorgulamanin yaninda belli bir degerden öncekini yada sonrakini, bir degiskenin en küçük yada en büyük degerlerini sorgulayabilirsiniz.

Önceden tanimlanmis en önemli üç ordinal tip Integer, Boolean, ve Char (character) ‘ dir. Asagidaki tablo sayilarin gösterimi için kullanilan ordinal tipleri listelemektedir.

Size SignedRange

UnsignedRange

8 bits ShortInt-128 to 127

Byte0 to 255

16 bits SmallInt-32768 to 32767

Word0 to 65,535

32 bitsLongInt-2,147,483,648 to 2,147,483,647

LongWord (since Delphi 4)0 to 4,294,967,295

64 bits Int64

16/32 bits Integer Cardinal

Sizinde göreceginiz gibi bu tipler degisik araliklardaki sayilarin kullanilan bitlere ve isaret bitinin kullanimina göre degiskenligini göstermektedir. Isaretli sayilar daha düsük aralikta deger alirlar çünkü bit bit sayinin isaretini belirlemek için kullanilir. Bir sonraki bölümde anlatilan Range adindaki örnegi kullanarak sayi araliklarini teshis edebilirsiniz.

Delphi 4’ deki Integral Tipler :

Delphi 3 te isaretsiz sayilar 31 bitlik Cardinal tipler ile gösterilirdi.(2 megabayte). Delphi 4 de LongWord adinda yeni bir tip gelistirildi. 32 bit genisliginde ve 4 megabyte’a kadar deger alabiliyor. Cardinal tip LongWord ün yeni bir takma adi sayilabilir. LongWord 2 megabyte ve fazlasini barindirabilir. Dahada ilerisi bu tip sayilarin CPU da gerçek gösterimi ile aynidir.

Delphi 4 ile gelistirilen yeni bir tipte Int 64 tipidir. 18 basamaga kadar tamsayilarin gösterimini saglar. Bu tip bazi ordinal tip rutinler tarafindan desteklenir (Low ve High, Inc ve Dec, IntToStr gibi) . Karakter dizisinden sayiya çevirme isleminde ise iki yeni fonksiyon gelistirilmistir bunlar StrToInt64 ve StrToInt64Def.

Boolean :

Boolean degerler, Boolean tiplere nazaran daha seyrekkullanilirlar. Bazi Boolean degerlerin Windows API fonksiyonlarinda kullanimi için özel gösterim tipleri gerekir. Bu tipler ByteBool, WordBool, LongBool’dur.

Delphi 3’de , Visual Basic ve OLE otomasyonu ile birlikteligi saglamak için ByteBool, WordBool ve LongBool veri tipleri degistirilmis True degerini göstermek için –1, False içinse 0 degeri kullanilmistir. Boolean veri tipi ise degistirilmemistir.

Karakterler:

Son olarak karakterler için iki farkli gösterim sekli bulunur. ANSIChar ve WideChar. Ilk tip 8 bitlik bir karakter degiskenidir ve Windows tarafindan kullanilan ANSI karakter setine karsilik kullanilir. Ikincisi 16 bitlik karakterlerdir. Bu karakter tipi NT tarafindan desteklenirken windows 95 ve 98 tarafinda kismi olarak desteklenen UNICODE karakterler için kullanilir. Çogu zaman ANSIChar için Char tipini kullanacaksiniz, unutmamaniz gereken ilk 256 Unicode karakeri ANSIChar ile aynidir.

Page 15: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Sabit karakter degerleri ‘k’ da oldugu gibi kendi degerleri ile yada sayisal olarak #78 olarak gösterilebilir. Bu harf Ord fonksiyonunu kullanarakta gösterilebilir Ord(78) gibi.

Genelde sembolleri, rakamlari ve harfleri belirtmek için sembolik gösterimlerini kullanmak daha iyidir. Asagidakiler çok kullanilan bir kaç özel karakteri göstermektedir:

#9     Tabulator#10    newline#13    carriage return (enter key)

Range Örnegi :

Degisik araliklardaki ordinal veri tipleri hakkinda fikir edinebilmeniz için Range adinda bir program yazdim. Bu programin çiktisi asagidaki sekilde görülmektedir.

Range programi basit bir form, 6 button ve Label bilesenlerinden olusmaktadir. Bazi Labellar static yazilari görüntülemek için kullanilmistir digerleride buttonlara kliklendiginde veri tipi hakkinda bilgi göstermek için kullanilmistir.

Sag tarafta bulunan Buttonlardan birine her basisinizda program soldaki Labellari güncellemektedir. Farkli etikerler veri tipini, kaç byte kullanildigini, minimum ve maximim degerlerini göstermektedir. her butonun kendine özgü OnClic metodu bulunmaktadir. Asagida Integer butonunun OnClick metodu na ait kod gösterilmektedir.

procedure TFormRange.BtnIntegerClick(Sender: TObject);begin  LabelType.Caption := 'Integer';  LabelSize.Caption := IntToStr (SizeOf (Integer));  LabelMax.Caption := IntToStr (High (Integer));  LabelMin.Caption := IntToStr (Low (Integer));end;

Delphi programla ile daha önceden bir deneyiminiz varsa programin nasil çalistigi konusunda fikir edinebilirsiniz. Yeni baslayanlar ise SizeOf, High veLow fonksiyonlarinin kullanimina dikkat etmelidir. SizeOf fonksiyonu integer bir deger geriye döndürür bu degeri karakter dizisine çevirmek için inttostr fonksiyonu kullanilir.

Diger butonlardaki kodlar ise buna çok fazla benzemektedir. Tek fark fonksiyonlara parametre olarak geçilen degerlerdedir. Asagidaki resimde ayni kodun 16 bitlik delphi ile windows 95 de tekrar derlendikten sonra çalistirilip alinan çiktisini göstermektedir. 16 ve 32 bitlik Integerin farkida buradan anlasilabilir.

Page 16: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Integer tipinin degeri kullanilan CPU ve isletim sistemine göre degisir. 16-bit windowsta Integer tipi 2 byte genisligindedir. 32 bitlik windowsta ise 4 byte genisligindedir. Bu yüzdendirki Range örnegini tekrar derlediginizde farkli çikti alirsiniz.

Integer tipinin iki farkli gösterimi bir problem degildir. Fakat 16 bitlik bir programda sayiyi bir dosyaya kaydedip 32 bit lik versiyonda bu dosyadan okumaya çalisirsaniz bazi sorunlar ile karsilasirsiniz. Böyle bir durumda platformdan bagimsi veri tipi seçmeniz gerekir (LongInt yada SmallInt gibi).

Ordinal Tip Rutinleri:

Routine Amacı

Dec parametre olarak geçilen değeri bir azaltır yada ikinci bir parametre geçildiyse bu parametrenin değeri kadar azaltır.

Inc parametre olarak geçilen değeri bir yada belirtilen değerce arttırır.

Odd Argumen tek bir sayıysa True değerini geri dönderir

Pred Bir önceki değeri dönderir.

Succ Sonraki değeri dönderir.

Ord Argumanın küme içerisindeki sırasını dönderir

Low Parametre olarak geçilen tipin en küçük değerini dönderir.

High En büyük değerini dönderir.

Gerçel Tipler:

Gerçel tipler kayan noktali sayilarin farkli formatlarda gösterimini saglar. En küçük tip Single dir ve 4 byte ile emsil edilirler. Double kayan noktali sayilar 8 byte ile gösterilirken Extended tipler ise 10 byte ile temsil edilir. Bunlarin hepsi kayan noktali veri tiplerinin degisik tanim araliklarindaki gösterimleridir. ve IEEE standarlarindadir. CPU tarafindan direkt olarak desteklenir.

Delphi2 ve Delphi3 de Gerçel tipler 16 bitlik versiyondaki gibi gösterilmekteydi ve 48bitti. Fakat Borland bunu degistirdi Single Double veExtended tiplerini getirdi. bunun sebebi 6bit kayan noktali sayi ne Intel CPU lari tarafindan desteklenmekte nede IEEE standartlari tarafindan. Bu problemin üstesinden gelmek için Gerçel tip 48 bitlik gösterim seklini aldi.

Bunun yaninda 2 degisik veri tipide bulunmakta: Comp büyük tamsayilar için 8 bytelik bir gösterimdir Currency ise 4 basamak ondalik kisim olmak üzere Comp gibi 64 bittir.

Gerçel tipler için Range gibi bir örnek program yapamiyoruz çünkü Ordinal tipler için kullanilan High ve Low gibi fonksiyonlari burada kullanamiyoruz. nedenini ise bir örnekle açiklayalim mesele Integer tipinde 23 degerini ele alalim bunun bir sonraki ve önceki degerleri bellidir fakar Gerçel tipteki 23ün belli degildir, yani bir sonraki deger 23.1 de olabilir 23.00001 de olabilir.

Page 17: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

DATE ve TIME:

Delphi, Date ve time degerlerini tutmak içinde gerçel tipler kullanmaktadir. Daha sade olmasi için Delphi TDateTime adinda bir veri tipi gelistirmistir. Bu bir kayan noktali veri tipidir çünkü yil ay gün saat dakika saniye ve milisaniyye kadar bilgileri tutmak için yeteri kadar genis veri araligina sahiptir. Date bilgileri integer kisimda Time bilgileri ise kesirli kisimda tutulmaktadir.

type  TDateTime = type Double;

Seklinde tanimlanmistir. TDateTime’in kullanimi oldukça basittir, çünkü Delphi bu veri tipi için asagidaki tabloda bulunan fonksiyonlari tanimlamistir.

Routine Description

Now Returns the current date and time into a single TDateTime value.

Date Returns only the current date.

Time Returns only the current time.

DateTimeToStrConverts a date and time value into a string, using default formatting; to have more control on the conversion use the FormatDateTime function instead.

DateTimeToString Copies the date and time values into a string buffer, with default formatting.

DateToStr Converts the date portion of a TDateTime value into a string.

TimeToStr Converts the time portion of a TDateTime value into a string.

FormatDateTimeFormats a date and time using the specified format; you can specify which values you want to see and which format to use, providing a complex format string.

StrToDateTime Converts a string with date and time information to a TDateTime value, raising an exception in case of an error in the format of the string.

StrToDate Converts a string with a date value into the TDateTime format.

StrToTime Converts a string with a time value into the TDateTime format.

DayOfWeek Returns the number corresponding to the day of the week of the TDateTime value passed as parameter.

DecodeDate Retrieves the year, month, and day values from a date value.

DecodeTime Retrieves out of a time value.

EncodeDate Turns year, month, and day values into a TDateTime value.

EncodeTime Turns hour, minute, second, and millisecond values into a TDateTime value.

Bu veri tipi ve rutinlerinin kullanimini göstermek için TimeNow adinda örnegi gelistirdim. Bu örnegin ana formu bir adet buton ve ListBox bileseninden olusmakta. Program çalismaya basladiginda o anki tarih ve saati otomatik olarak hesaplayip göstermektedir. Daha sonra butona her basilisinda programin çalismaya baslamasindan itibaren ne kadar aman geçtigini gösterir.

iste formun OnCreate olayina yazdigim kod:

procedure TFormTimeNow.FormCreate(Sender: TObject);begin   StartTime := Now;  ListBox1.Items.Add (TimeToStr (StartTime));

Page 18: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

  ListBox1.Items.Add (DateToStr (StartTime));  ListBox1.Items.Add ('geçen zamani görmek için butona basin.');end;

ilk komut Now fonksiyonunu çagirmakta ve o anki tarih ve saati StartTime adindaki global degiskende saklamaktadir.

var   FormTimeNow: TFormTimeNow;  StartTime: TDateTime;

Ben sadece ikinci tanimlamayi ekledim birincisi Delphi terafindan saglandi.

var  Form1: TForm1;

Formun ismi degistirildiginde bu tanimda otomatik olarak güncellenecektir. Global degisken kullanmak iyi bir yaklasim degildir formun private kisminada yazilabilirdi. Fakat bu konu Nesneye yönelik programlamaya girmekte. sonraki üç komut ListBox bilesenine 3 madde eklemektedirilki saat ikincisi tarih ve üçüncüsüde bir mesajdir. Örnegin çiktisi asagidaki gibidir:

procedure TFormTimeNow.ButtonElapsedClick(Sender: TObject);var StopTime: TDateTime;begin  StopTime := Now;  ListBox1.Items [2] := FormatDateTime ('hh:nn:ss', StopTime - StartTime);end;

Yukaridaki komut yeni tarih ve saati alip baslangiç bilgileri ile arasindaki farki hesaplamaktadir. Bu sebeple baslangiç tarih ve saatini tutmak için global degisken tanimladik.

TimetoStr ve DateToStr fonksiyonlarinin yaninda son örnekte yaptigim gibi FormatDateTime fonksiyonunuda kullanabilirsiniz. Tarih ve saat degerinin windows un uluslararasi ayarlarina göre karakter dizisine cevirildigine dikkat edin. Bu uluslar arasi ayarlar asagida tanimlanan degiskenlerde tutulur.

DateSeparator: Char;ShortDateFormat: string;LongDateFormat: string;TimeSeparator: Char;TimeAMString: string;TimePMString: string;ShortTimeFormat: string;

Page 19: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

LongTimeFormat: string;ShortMonthNames: array [1..12] of string;LongMonthNames: array [1..12] of string;ShortDayNames: array [1..7] of string;LongDayNames: array [1..7] of string;

Kayan noktali sayilar ve Currency tipi için daha fazla sabit bulunmaktadir bu konudaki bilgi için Delphi Help File da Currency and date/time formatting variables basligindaki konuya bakiniz.

Özel Windows Tipleri:

Simdiye kadar gördügümüz önceden tanimli veri tipleri Delphiye aitti. Delphi windows tarafindan önceden tanimlanmis veri tiplerinede yer verir. Bu veri tipleri dilin integral kismini olusturmamaktadir fakat Windows kütüphanesinde bulunmaktaadirlar. Windows tipleri yeni birmler içermektedir bunlar DWORD yada UINT gibi tiplerdir, bir çok kayit(yapi) , birçok pointer tipi ve dahasi.

Windows tipleri arasinda en önemlisi Handle tipidir. Bu veri tipinin adi THandle’ dir ve windowsta söyle tanimlanmistir.

typeTHandle = Integer;

Handle data tipi bir sayilar gibi tanimlanmistir fakat onlar gibi kullanilmamaktadir. Windowsta handle, sitemdeki veri yapisinin içerigine yapilan bir referanstir. Mesela bir pencere ile çalistiginizda (örnegin Delphi formu), sistem size bu pencereyi referans gösteren bir handle verir. Mesela sistem size derki çalistiginiz pencerenin numarasi 142 dir. Bu noktadan sonra programiniz sisteme 142 nolu pencereyi küçült, büyült yada yeniden boyutlandir der. Bir çok windows API fonksiyonu ilk parametre olarak bir handle alir.

Diger bir degisle, handle (tutamaç) sistem tarafindan tutulan özel bir elemana (bitmap, form, pencere, icon memory block gibi) yapilan referanstir. Delphide tutamaçlara nadiren ihtiyaç duyarsiniz çünkü formlar, bitmapler vs. içinde gizli olarak tutulurlar. Bunlari sadece Delphinin desteklemedigi Windows API fonksiyonlarini çagirirken kullaniriz.

NOT : Handle tipinin büyüklügü 16 bit ve 32 bit windowta farklilik gösterir. Bu yüzden farkli platformlarda çalisan programlar yazarken dikkatli olmak gerekir.

Typecasting ve Tip Dönüsümü :

Daha öncede gördügümüz gibi farkli tiplerden degiskenleri birbirlerine atayamiyorduk. Bu tür bir kisitlamayi asmanin iki yolu bulunmakta. Birincisi hedef veri tipinin adini fonksiyon ismi olarak kullanan basit bir fonksiyon tanimi Typecasting dir.

Örnek :

var  N: Integer;  C: Char;  B: Boolean;begin  N := Integer ('X');  C := Char (N);  B := Boolean (0);

Ayni boyutlara sahip iki veri tipi arasinda typecasting yapabilirsiniz. Iki ordinal yada gerçel veri tipi arasinda yapilan typecasting genellikle güvenli olur. Ne yaptiginizi tam olarak bilmiyorsaniz iki pointer tipi arasinda yapilacak typecasting güvenli degildir.

Page 20: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Genelde casting islemi tehlikeli bir programlama teknigidir. Çünkü verinin gösterildigi sekilden farkli bir yapida gösterilmesine tesebbüs edersiniz. Ve veri tiplerinin iç yapilari, bellekteki yerlesim sekilleri farkli oldugundan engellenmesi güç hatalarla karsilasilabilir. Bu sebeptencasting isleminden kaçinmak gerekir.

Ikinci metod tip çevrim metodlarini kullanmaktir. Asagidaki tabloda farkli tipler arasinda dönüsümü saglayan metodlar siralanmistir. Dikkat ederseniz tabloda bazi özel tipler için kullanilan metodlar bulunmamaktadir (mesela TDateTime gibi).

Routine Description Chr Converts an ordinal number into an ANSI character.

Ord Converts an ordinal-type value into the number indicating its order.

Round Converts a real-type value into an Integer-type value, rounding its value.

Trunc Converts a real-type value into an Integer-type value, truncating its value.

Int Returns the Integer part of the floating-point value argument.

IntToStr Converts a number into a string.

IntToHex Converts a number into a string with its hexadecimal representation.

StrToInt Converts a string into a number, raising an exception if the string does not represent a valid integer.

StrToIntDef Converts a string into a number, using a default value if the string is not correct.

Val Converts a string into a number (traditional Turbo Pascal routine, available for compatibility).

StrConverts a number into a string, using formatting parameters (traditional Turbo Pascal routine, available for compatibility).

StrPasConverts a null-terminated string into a Pascal-style string. This conversion is automatically done for AnsiStrings in 32-bit Delphi. (See the section on strings later in this chapter.)

StrPCopyCopies a Pascal-style string into a null-terminated string. This conversion is done with a simple PChar cast in 32-bit Delphi. (See the section on strings later in this chapter.)

StrPLCopy Copies a portion of a Pascal-style string into a null-terminated string.

FloatToDecimal Converts a floating-point value to record including its decimal representation (exponent, digits, sign).

FloatToStr Converts the floating-point value to its string representation using default formatting.

FloatToStrF Converts the floating-point value to its string representation using the specified formatting.

FloatToText Copies the floating-point value to a string buffer, using the specified formatting.

FloatToTextFmt As the previous routine, copies the floating-point value to a string buffer, using the specified formatting.

Page 21: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

StrToFloat Converts the given Pascal string to a floating-point value.

TextToFloat Converts the given null-terminated string to a floating-point value.

BÖLÜM 4 : Kullanıci Tanimlı Veri Tipleri

Halihazırda veri tiplerinin kullanıma sunulmasından sonra Pascal dili ile beraber gelen en önemli özelliklerden biride yeni veri tiplerini tanımlama olanağıdır.Kullanıcılar Type bildirimi ile alt tipler, diziler, record tipleri, enumerated tip, pointer ve küme tipleri gibi yeni tipler yaratabilirler. En önemli kullanıcı tanımlı veri tipi Class’lardır. Bu konu Object pascalın Object Oriented uzantısıdır ve bu konu hakkında bahsedilmeyecektir.

Yeni tip tanımına olanak veren birçok programlama dili bulunmaktadır. Pascal bunlar arasında en sade ve formal yolla tip tanımı yapan dillerdendir.

Adlı ve Adsız Tipler

Bu çeşit tiplere sonradan kullanılmak üzere bir ad verilebilir yada bir değişkene direkt olarak uygulanabilir. Bir veri tipine ad verdiğiniz zaman program kodu içerisinde özelbir bölüm içerisinde belirtmeniz gerekir. Örneğin :type// Alt tip tanımıBuyukharfler = 'A'..'Z';// dizi tanımı definitionSicakliklar = array [1..24] of Integer;

// record tanimiTarih = recordAy: Byte;Gun: Byte;Yil: Integer;end;

// enumerated tip tanimiRenkler = (Kirmizi, Sari, Yesil, Mavi, Turuncu, Pembe);

// Küme TanimiLetters = set of Char;

Benzer tip tanımları direkt olarak bir değişken tanımlamak için şöyle kullanılabilir.

varOcakSicakliklari: array [1..31] of Byte;RwnkKodu: array [Kirmizi..Pembe] of Word;Palet: set of Renkler;

NOT: Genelde yukarıdaki örnekteki gibi adsız veri tiplerinden kaçınmanız gerekir, çünkü bunlari parametre olarak gönderemediğiniz gibi ayni tipten verileri tanimlamanızda zorlaşır. Pascalda tip tanımlama kuralları ve tipler arasındaki uyum, tiplerin adları üzerine kurulmuştur. Örneğin a ve b diye iki değişken tanımladık ve bunlar 1..100 arası değer alabilen değişkenler. Tipleri ise kullanıcı tarafından tanımlanmış ve tip isimleri a ve b değişkenleri için farklı olsun. Her nekadarda bu iki değişkenin aldığı değer aralığı aynı olsada tip isimleri farklı olduğu için Derleyici tarafından farklı tipler olarak algılanır. Adsız tipler içinse compiler tarafından bir isim ataması yapılır. Karmaşık yapıdaki değişkenler için yeni veri tipleri tanımlayarak, bu iş için harcayacağınız zamana deydiğini göreceksiniz.

Page 22: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Bu tip tanımlamasıda ne anlama geliyor diyebiliriniz? Bu konuya acıklık getrmsi için Pascalda tip tanımlamasının nasıl yapıldığını anlatacağım. Bunun yanı sıra diğer diller ile arasındakı farkıda gostererek bu konuyu zaten bilenlerinde ilgisini b noktaya toplamaya çalışacağım. Son olarakta birkaç delphi orneği ve araçlardan bahsedip dinamik olarak tip bilgilerin nasıl erişileceğini göstereceğim.

SUBRANGE TİPLER

Subrange veri tipi varolan veri tiplerinin tanım aralığının dahada kısıtlanması ile oluşturulan veri tipleridi. Daha önceden tanumlı olan Integer veri tipini kullanarak 1..10 arasında değer alan yeni bir subrange veri tipi oluşturabilirsiniz. Yada Char veri tipini kullanarak aşağıdaki gibi yeni bir subrange veri tipi oluşturabilirsiniz.

typeON = 1..10;YuzUzeri = 100..1000;BuyukHarf = 'A'..'Z';

Subrange veri tipi oluştururkn ana veri tipini belirtmek zorunda değilsiniz. Sadece ana veri tipinin iki sabtini belirtmeniz gerekir. Orjina veri tipi ordinal tipte olmali ve yeni oluşturulan veri tipide ordinal tipte olacaktir. Eğer subrange bir veri tipi tanımladıysanız bu tiptek değişkene atayacağınız değer aralığı tipin alt ve ust değerleri ile sınırlıdır.

Örneğlin aşağıdaki kod geçerli bir örnektir:

varBharf : BuyukHarf;beginBHarf := 'F';

Fakat aşağıdaki kod geçerli bir kod değildir

varBHarf: BuyukHarf;beginBHarf := 'e'; // compile-time hatası

Delphi yukarıdaki kodu derleyecektir fakat Range Checking Compiler opsiyonunu seçtiyseniz. Range Check Error hatasını alacaksınız.

NOT: Size önerim bu opsiyonu açık bırakmanız olacaktır. Böylece daha güvenilir ve hatalrı kolayca ayılayableceğiniz bir program geliştirmiş olursunuz. Yada bu opsiyonu kapatıp programın son halini derlerken açarak biraz hız kazanmış olursunuz. Her halükarda kazanacağınız hız fazla olmayacaktır bu sebeple opsiyonu açık bırakmnızı öneririm. Bu önerim stack ve overfow opsiyonları içinde geçerli olacaktır.

ENUMERATED TİPLER

Enumerated veri tipi kulanıcı taımlı veri tipinin başka br çeşididir. Varolan bir tipin değişim aralığını vermek yerine, olası biin değerleri yeni yaratacağınız tipte belirtmeniz gerekir. Diğer bir deyişle enumerated veri tipi bir değerlr listesidir. İşte birkaç örnek :

TypeRenkler = (Kirmizi, Sari, Yeşil, Mavi, Turuncu);Kartlar = (Kupa, Papaz, vale);

Listedeki her değer 0 dan başlayan ordinal bir değere sahiptir. Eğer bu listedeki değerlerden birisini ord fonksiyonu ile birlikte kulanırsanız sıfırı temel alan bir değerin geri donduğünü görürsünüz. Örneğin ord(Sari) 1 değerini geri dönderecektir.

Page 23: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

NOT: Enumerated veri tipleri Delphi içerisinde 8 bitlik bir değer ile gösterilir. Eğer listeniz 256 elemandan fazlaysa Delphi 16bit lik bir gösterim kullanır. Bunun yanında 32 bitlik gösterimde bulunmatadır böylelikle C ve C++ uyumluluğuda sağlanmış olur. Varsayım olarak kullanılan 8 bitlik gosterimi değiştieblir ve 16 yada 32 bit yapabilirsiniz bunun için $Z compiler direktifini kullanabilirsiniz. Delphideki VCL(Visual Component Library) enumerated veri tiplerini birçok yerde kullanmaktadır. Mesela Border”ın style”I şöyle tanımlanmıştır

typeTFormBorderStyle = (bsNone, bsSingle, bsSizeable, bsDialog, bsSizeToolWin, bsToolWindow);

Eğer değer özelliği enumerated veri tipinde ise bu değerleri Object inspector penceresinden seçebilirsiniz.

Şekil 4.1 : Object Inspecter penceresinde enumerated veri tipi

SET (KÜME) TİPİ

Set tipi bir gurup değerden oluşmaktadır. Bu değerler kümenin üzerine kurulmuş olduğu ordinal veri tipine göre belirtilirler. Bu ordinal veri tipleri genellikle sınırlıdır, enumerated yada ordnal tpte gösterlir. Eğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri.

Bir değişken tanım aralğındaki değerlerden yalnızca birini alır. Halbuki küme tipi ile tanımlanmış bir değişken bırden fazla değer alabilir. Bir küme değişkeni içerisinde bırden fazla değer tanımlamak için köşeli parantez içerisinde virgullerle ayrılmış değerleri yazmamız yeterli olacaktır. İştesize bir örnek :

typeHarfler = set of buyukharf;

Şimdi bu tipte bu tipte bir değişken tanımlayıp ordınal tipte birkaç değer atayabiliriz. Aşadaki örnek birdeğişkene değerlerin nasıl atandığını gstermekte.

varharfler1, harfler2, harfler3: harfler;beginharfler1 := ['A', 'B', 'C'];harfler2 := ['K'];harfler3 := [];

Bir pencerenin border”I için mümkün olan değerleri aşağıdaki kod ile belirtmekte mümkündür Delphi içerisndede aynı kod kullanılmaktadır.

type TBorderIcon = (biSystemMenu, biMinimize, biMaximize, biHelp);TBorderIcons = set of TBorderIcon;

Page 24: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Bu tanımla bir pencerenin icon türünü belirleriz. Object ınspector penceresinden herhangi bir formun borderıcons özelliğini çift tıkladığınız zaman açılan alt özellikleri true yada false yaparak kümeye dahil edebilirsiniz.

Set veri tipi üzerine kurulmuş diğer bir özellikte yazı fontunun sitilidir. Mümkün olan değerler bold, italik, underline, ve striketheough dur. Ve tabiki yazının stili bu özelliklerden bir yada daha fazlası olabilir. Böyle bir kümeye programodu yazarak değer ataabilmek için aşağıdaki örneği inceleyiniz.

Font.Style := []; // sitilsizFont.Style := [fsBold]; // kalın yazı sitiliFont.Style := [fsBold, fsItalic]; // hem italik hem kaın yazı

Ve tabiki iki kümeyi kullanarakda işlem yapabilirsiniz. Mesela iki kümenin kesişimini yada brleşimini almak gibi işlemleri geröekleştirebilirsiniz.

Font.Style := OldStyle + [fsUnderline]; // iki küme

ARRAY (DİZİ) TİPLERİ

Array veri tipi belirli sayı ve tipteki elemanların liste şeklinde tanımıdır. Array’in herhangi bir elemanına köşeli parantez içerisinde bir endeks numarısı ile erişilir. Köşeli parantezler ayrıca array tanımı yapılırken array’in boyutlarını belirlemek içinde kullanılır. Örneğin aşağıdaki kod ile 24 tane integer veri tipinde bir array yapısı oluşturulur.

typeSicaklikListesi = array [1..24] of Integer;

Arrayın tanımı gereği, bir array tipi tanımlarken köşeli parantezler içerisinde o array’in boyutları belirtilmelidir. İkinci bir yöntem ise köşeli paratez içerisinde ordinal veri tiplerini kullanılarak bu boyutların belirlenmesidir.

Bu sınırlar array’in geçerli olan boyutlarını belirler. Bir array veri tipinin alt ve üst sınırlarını tanımladıktan sonra C, C++, Java ve diğer programlama dillerinde olduğu gibi sıfır tabanlı bir endeks oluşturma zorunluluğu yoktur.

Bir array’in alt ve üst sınırlarını tanımladığımıza göre Delphi önceden bildiğimiz üzere bu aralığın geçerliliğini kontrol eder. Bu sınırlar dışında bir endeks kullanıldığı zaman Compiler opsiyonlarındaki seçeneklere bağlı olarak ya derleme esnasında yada çalışma esnasında ‘invalid constant subrange’ geçersiz endeks aralığı hatası alınır. Array yapısının yukarıda yapılmış olan tanımını kullanarak SicaklikListesi veri tipinin GunlukSicaklik1 adındaki değişkenini şu şekilde yapılandırabilirsiniz:

typeSicaklikListesi = array [1..24] of Integer;

varGunlukSicaklik1: SicaklikListesi;

Page 25: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

procedure SicaklikTanimlama; begin GunlukSicaklik1 [1] := 54;GunlukSicaklik1 [2] := 52;...GunlukSicaklik1 [24] := 66;GunlukSicaklik1 [25] := 67; // derleme – zamanı hatası

Array veri tipi aşağıdaki örnekte görüldüü gibi çok boyutlu olabilir:

typeAylikSicakliklar = array [1..24, 1..31] of Integer;YillikSicakliklar = array [1..24, 1..31, Jan..Dec] of Integer;

Bu iki array tipide aynı temel veri tiplerini kullanmaktadır. Bu yüzden aşağıdaki kodda olduğu gibi tanımlanabilirler:

typeAylikSicakliklar = array [1..31] of GunlukSicaklik1;YillikSicakliklar = array [Jan..Dec] of AylikSicakliklar;

Yukarıdaki tanımlama şekli ile endeks sirasi ters çevirilmiş oldu, fakat yinede verilerin bir blok halinde iki değişken arasında aktarımına izin vermektedir. Örneğin aşağıdaki kod ile Ocak ayı sıcaklıkları şubat ayına kopyalanmaktadır:

varBuYil: YillikSicakliklar;begin...BuYil[Subat] := BuYil[Ocak];

Sıfır tabanlı bir array tipi yaratmak içinse, array’in taban sinirini sıfır yapmanız yeterli olacaktir. Genelde mantıksal sınırlar yaratmak daha avantajlıdır, çünkü array’in 3. elemanına erişmek için 2 yazmanıza gerek kalmaz(sıfır tabanlı dizide 3. elemanın endeksi 2’dir ). Hernekadarda windows sıfır tabanlı array tipini kullansada (çünkü C programlama dili kullanılmıştır.), Delphi bileşen kütüphaneside aynı eğilimdedir.

Eğer array veri tipi ile çalışmak durumunda kalırsanız, Low ve High fonksiyonlarını kullanarak bu array’in alt ve üst sınırlarını öğrenebilirsiniz. Low ve High fonksiyonlarının kullanımı tavsiye edilir , özellikle döngülerde, çünkü program kodunu array’in alt ve üst sınırlarından bağımsız kılar. İleride array’in alt ve üst sınırlarını değiştirdiğinizde Low ve High fonksiyonları eskisi gibi işlevlerini sürdüreceklerdir. Eğer bu fonksiyonlar kullanılmamış olsaydı döngülerdeki kodlarıda güncellemeniz gerekecekti. Low ve High fonksiyonları program kodunuzu daha okunaklı ve kolay anlaşılır kılacaktır.

NOT : Bu arada Low ve High fonksiyonlarının kullanımı çalışma zamanı hataları alınmayacağı anlamına gelmemelidir. Çünkü bu ve bunu gibi bazı sistem fonksiyonları geri döndermeleri geren değerleri çalışma esnasında değilde derleme esnasında yaparlar ve kod derlendiği zaman Low ve High yerine sabit değerler atanır.

NOT: Delphi4 Object Pascal Dinamik array veri tipinide bir yenilik olarak getirmiştir. Bu özellik sayesinde array’lerin alt ve üst sınırları çalışma kipi esnasında dinamik olarak attırılıp azaltılabilir. Bu konu hakkındaki bilgiyi bölüm 8 de bulabilirsiniz.

RECORD TİPLERİ

Record veri tipi farklı tiplerin tek bir tip altında toplanması sağlar. Record tipinin her bir elemanı kendine has bir veri tipine sahiptir. Record veri tipi ileride kullanılmak üzere bu alanlara birer ad verir. Aşağıda Record veri tipinin tanımı ve bu tipin kullanımı ile ilgili küçük bir örnek bulacaksınız.

Page 26: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

typeTarih = recordYil: Integer;Ay: Byte;Gun: Byte;end;

varDogumGunu: Tarih;

beginDogumGunu.Til := 1997;DogumGunu.Ay := 2;DogumGunu.Gun := 14;

Class’lar ve Object’ler (sınıflar ve nesneler) record veri tipinin genişletilmiş hali olarak düşünülebilir. Delphi kütüphaneleri record tipi yerine Class kullanımına eğilimlidir, fakat bir çok record veri tipi Windows API’lerinde tanımlıdır.

Record veri tipide değişken yapıda alanlara sahip olabilir, yani birden fazla farklı veri tipindeki alan aynı hafıza alanını paylaşabilir. ( C programlama dilindeki Union gibi). Değişken record tipi kullanımı Delphide Nesneye yönelim ve ileri programlama teknikleri ile yerini değiştirmiştir.

Değişken tipteki record kullanımı iyi bir programlama tekniği olmadığından özellikle eni başlayanlar için pek tavsiye edilmez. Uzman kullanıcılar için sorun yok zira Delphinin çekirdek kütüphane kodlarındada bu kullanım tarzına rastlanmaktadır.

POINTER’LAR

Pointer veri tipi başka değişkenlerin hafızadaki adreslerini tutmaya yarayan farklı br veri tipidir. Bu yüzden pointer veri tipi bir veriye dolaylı yoldan gösterim tarzıdır. Pointer tanımı yapmak için özel bir kelime kullanılmaz aksine bir sembol kullanılır. Bu özel sembol (^)’ dür.

typePointerToInt = ^Integer;

Pointer değişkenini tanımladıktan sonra bu değişkene aynı tipteki başka bir değişkenin adresini @ sembolünü kullanarak atayabilirsiniz.

varP: ^Integer;X: Integer;

beginP := @X;// değeri iki farklı şekilde değiştirbiliriz.X := 10;P^ := 20;

P adındaki pointer ile o pointer gösterdiği adrese erişirsiniz, o adresin içerisindeki veriye erişmek için p^ yazımını kullanmak gerekir.

Mevcut bir hafıza alanına erişmek yerine New yordamı ile dinamik olarak ayrılan yeni bir hafıza alanınada erişilebilir. Bu yolla ayırdığınız hafıza alanına ihtiyacınız kalmadığında dispose yordamını kullanarak bu alanı ana hafızaya tekrar kazandırabilirsiniz.

varP: ^Integer;

begin

Page 27: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

// initializationNew (P);// operationsP^ := 20;ShowMessage (IntToStr (P^));// terminationDispose (P);end;

Eğer pointer değişkeninize bir değer atanmamışsa ona nil değerini atayabilirsiniz bu sayede değişkene bir değerin atanıp atanmadığını nil değeri ile karşılaştırarak bulabilirsiniz.

procedure TFormGPF.BtnGpfClick(Sender: TObject);varP: ^Integer;

beginP := nil;ShowMessage (IntToStr (P^));end;

Yukarıdaki kod ile P pointerına nil değeri atanıştır yani P pointeri hiçbir adresi göstermemektedir dolayısı ile showmessage komutunun işletilmesi ile aşagıda gösterilen hata mesajı alınır.

Aşağıdaki kod ile daha güvenli bir program yazılmış olunur. Çünkü P pointerinin içeri boşsa yani nil ise bir sonraki komut işletilmemektedir.

procedure TFormGPF.BtnSafeClick(Sender: TObject);varP: ^Integer;X: Integer;

beginP := @X;X := 100;if P <> nil thenShowMessage (IntToStr (P^));end;

Delphi belli bir tipte olmayan pointerlarda tanımlayabilir( C dilindeki void* gibi). Eğer tipi belirli olmayan bir pointer kullanacaksanız New yerine GetMem yordamını kullanmanız gerekir. GetMem yordamı dinamik olarak ayrılacak hafıza alanının boyutları belirlenemediği zaman kullanılır.

Page 28: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Delphide pointer’lara nadiran ihtiyaç duyuluyor olmasına rağme bu ilginç bir avantajdır. Buna rağmen Pointer kavramını iyi anlama Delphinin arka plandaki object modelini anlamanın en önemli yoludur.

NOT: Delphide pointerları sık kullanmıyor olmanıza rağmen her bir obje aslında gerçek veriyi gösteren pointer’dır. Herşeye rağmen işin bu kısmı programcıya görünmez ve objeler birer veri tipi gibi kullanılır.

FILE TİPLERİ

Pascal’a özgü diğer bir tipte File tipidir. File veri tipi disk üzerindeki fiziksel bir dosyayı göstermek amacı ile kullanır. Yeni bir File veri tipini şöyle tanımlarsınız :

type IntegerDosya = file of Integer;

Bu tanımlamayı yaptıktan sonra bu dosyaya integer tipteki verileri yazıp okuyabilirsiniz.

BÖLÜM 5 : Statements

   Pascal'ın temeli veri yapıları ile Statementlar üzerine kurulmuştur. Bir programlama dilindeki stetementlar anahtar kelimeler ve diğer elementlerin bir araya gelmesiyle programın bir dizi işlemleri gerçekleştirmesini sağlarlar. Bir sonraki bölümdede göreceğimiz gibi statement lar procedure ve fonksiyonların oluşumunu sağlarlar. Şimdi program yazmamız için gerekecek temel komutlar üzerinde duralım.

Basit ve bileşik Statementlar:    

    Eğer Pascaldaki bir statement, içerisinde başka bir statement barındırmıyorsa buna basit statement denir. Bu türe örnek olarak procdurelerin işletilemesi için kullanılanlar ve atama işlemleri için kullandığımız statementları örnek verebiliriz. Basit statementlar noktalı virgüller ile birbirlerinden ayrılır :

X := Y + Z; // atama Randomize; // procedure çağrısı

Genelde statementlar "begin" ve "end" kelimeleri arasında yer alan bileşik statementların birer parçasıdır. Örneğin :

begin  A := B;  C := A * 2;end;

“end” kelimesinden önceki statement’ın sonuna noktalı virgül koyulmasına gerek yoktur. Örnek:

begin A := B; C := A * 2end;

İki farklı yazım şeklide doğrudur. ilk kod gereksiz bir noktalı virgül içermektedir. Bu statement bir Null statement’tır, yani kodu olmayan(boş). Null statementların bazı durumlarda döngüler yada bazı özel durumlarda kullanılabileceğine dikkat ediniz.

Not : Bu son noktalı virgül işe yaramasada kullanmaktayım, sizinde kullanmanızı tavsiye ederim çünkü daha sonra bu koda ilave yapmak isteyebilirsiniz.

Page 29: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Atama Statementları:

Pascalda atama işlemleri iki nokta üstüste ve eşittir işaretlerinin birlikte kullanılması ile yapılır. Bu notasyon diğer program dillerini kullananlar için alışık gelmeyebilir. Diğer dillerde atama işareti olarak eşittir işareti kullanılırken, Pascalda bu işaret karşılaştırma, test etme amacı ile kullanılır.

Not: Pascal derleyicisi ( C derleyicisi gibi ) karşılaştırma ve atama işlemleri için iki farklı operatör kullanmaktadır. Bu statementlardaki işaretin test amaçlımı yoksa atama amaçlımı olduğunu anlamına bakmak yerine iki farklı operatör kullanarak gerçekleştirir buda hız kazandırmaktadır.

Farklı operatörlerin kullanımı kullanıcıların programı okumasınıda kolaylaştırmaktadır.

Conditional Statements :

Conditional Statement’lar belli bir koşula göre iki yoldan birisine ayrılmayı sağlarlar. Bu koşulu test ederek gerçekleşrirler. İki temel conditiolan statement yapısı vardır bunlar IF ve CASE yapılarıdır.

IF Conditional Statementlar :

If yapısı bir koşulun sağlanması durumunda işletilir yada (if-then-else) yapısı kullanılarak koşulun sağlanması durumunda farklı, sağlanmaması durumunda farklı bir işlem gerçekleştiri.

Koşul, boolean mantıksal veri yapısı ile gösterilir. Buna örnek bir kod için basit bir Delphi program örneği verileceğiz. Önce yeni bir uygulama açın, ve formun üzerine iki check box ve dört buton koyun. Butonların yada checkboxların isimlerini değiştirmeyin, fakat üzerlerine çift tıklayarak OnClick olaylarında ne yapmaları gerektiğini tanımlamak için kod sayafasına geçin. İşte ilk buton için bir IF koşul yapısı:

procedure TForm1.Button1Click(Sender: TObject);begin // basit if statement if CheckBox1.Checked then ShowMessage ('CheckBox1 onay kutusu işaretli')end;

Program çalışırken eğer birinci onay kutusu(CheckBox) işaretli ise basit bir mesaj örüntülenecektir. (Şekil : 5.1) ShowMessage fonksiyonunu kullandım çünkü Delpide kullanıcıya en basit şekilde mesaj görüntülemenin yolu budur.

Page 30: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Şekil 5.1 : CheckBox1 kutusu işaretliyken 1. butona basınca çıkan mesaj görüntüsü.

Eğer düğmeye bastığınızda herhangi bir mesaj almıyorsanız checkbox1 kutusu seçili drurumda değildir. Böyle bir durumu daha açık bir hale sokmak için ikinci butonun OnClick olayına (if-then-else) yapısını kuralım. Bunun için program tasarım aşamasında iken 2. butona çift tıklayarak OnClick olayına aşağıdaki kodu yazalım.

procedure TForm1.Button2Click(Sender: TObject);begin // if-then-else statement if CheckBox2.Checked then ShowMessage ('CheckBox2 kutusu seçili durumda') else ShowMessage ('CheckBox2 kutusu seçili değil');end;

İlk cümleden sonra ve else anahtar sözcüğünden önce noktalı virgül kullanılmamasına dikkat ediniz aksi halde derleyici bir hata verecektir. If-Then-Else yapısı basit bir cümledir bu sebeple araya bir noktalı virgül koyulamaz.

If cümlesi dahada karmaşık bir yapıda olabilir. Koşul cümlesi, ardışık koşullad dizisi haline getirilebilir. Bu işlem (and, or ve not) mantıksal operatörleri kullanılır. Yada if cümleciği yuvalanarak (ardışık halde) kullanılabilir.

Form üzerindeki son iki butonu bu işlemleri göstermek için kullanacağız:

procedure TForm1.Button3Click(Sender: TObject);begin // iki koşullu statement if CheckBox1.Checked and CheckBox2.Checked then ShowMessage ('İki CheckBox onay kutusu işaretli')end;

procedure TForm1.Button4Click(Sender: TObject);begin // Bileşik, yuvalanmış if statement if CheckBox1.Checked then if CheckBox2.Checked then ShowMessage ('CheckBox1 ve 2 işaretli') else ShowMessage ('Sadece CheckBox1 işaretli') else ShowMessage ( 'Checkbox1 işaretli değil, Checkbox2 yi kim önemser ki?')end;

İkinci kodu iyice inceleyip programı çalıştırarak herşeyi anladığınızdan emin olun. Eğer hala kuşgularınız ve sorularınız varsa benzer programlar yazarak çözümlemeye çalışın, anlamanın en iyi yoludur. Daha fazla CheckBox ekleyip kodda değişiklikler yaparak yeni programlar üretebilirsiniz.

Case Statement:

Eğer if kalıbı ile kurduğunuz koşul cümleleri karmaşık bir hale geliyor ise Case yapısını kullanabilirsiniz. Case yapısı tek bir değer, değer listesi yada bir değer aralığındaki elemanı seçmek için kullanılan ifadedir. Bu değerler sabitlerden oluşur bu sebeple tekil ve ordinal veri tipinde tanımlı olmaları gerekir. Son olarakta else cümlesi kullanılarak bu değerlerden hiç biri uymuyor ise yapılması gereken işlemler belirlenebilir. İşte iki küöük örnek program :

Page 31: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

case Sayi of 1: Text := 'Bir'; 2: Text := 'İki'; 3: Text := 'Üç';end;

case Karakter of '+' : Text := 'Toplama işareti'; '-' : Text := 'Çıkarma işareti'; '*', '/': Text := 'Çarpma yada bölme işareti'; '0'..'9': Text := 'Rakam'; 'a'..'z': Text := 'Küçük harf'; 'A'..'Z': Text := 'Büyük harf';else Text := 'Bilinmeyen karakter';end;

Pascal’da Döngüler :

   Pascal dili diğer dillerde mevcut olan for, while ve repeat gibi çoğu döngü yapısına sahiptir. Bu yapılar eğer önceden başka programla dili kullandıysanız yabancı gelmeyecektir bu sebeple üzerinde fazla durmayacağım.

For döngü yapısı:

  Pascaldaki for yapısı statementların her işletilişinde artan yada azalan bir sayaç temel alınarak tasarlanmıştır. aşağıda ilk on rakamı toplamak için For döngüsü kullanılarak yazılmış örnek program göreceksiniz:

var K: Integer;begin K := 0; for I := 1 to 10 do K := K + I;

Ters bir sayaç kullanılarakta aynı kod şöyle yazılır :

begin K := 0; for I := 10 downto 1 do K := K + I;

Diğer dillere göre pascaldaki for yapısı daha az esnektir. (Sayacı sadece birer birer arttırabilirsiniz) fakat anlaşılması kolaydır. Eğer daha karmaşık yada özgün bir sayaca sahip döngü yapısını oluşturmak isterseniz Repeat yada While döngü yapılarını kullanabilirsiniz.

Not : For döngüsünün sayacı için sayı kullanmak zorunluluğu yoktur. Ordinal tipte herhangi bir değer, karakter yada enumerated tipte bir değer olabilir.

While ve Repeat Statement’ları:

While-do ve Repeat-Until döngü yapıları arasındaki tek fark repeat until yapısının en az bir kere işletiliyor olmasıdır. Bunu aşağıdaki örneğe bakarak kolayca anlayabilirsiniz :

while (I < 100) and (J < 100) dobegin  // I ve J birşeyler hesaplamak için kullanır...

Page 32: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

  I := I + 1;  J := J + 1;end;

repeat// I ve J birşeyler hesaplamak için kullanır...  I := I + 1;  J := J + 1;until (I > 100) or (J > 100);

Eğer I ve J nin ilk değeri 100’den büyükse Repet-Until yapısı içerisindeki statementla en az birer defa işletilecektir.

İki yapı arasındaki diğer temel fark ise repeat-until yapısının ter yapıda çalışmasıdır yani olumsuz koşul devam ettiği sürece işletiliyor olması. Koşul sağlandığı takdirde döngüde durmuş olacaktır. Bu çalışma şekli While döngü yapısının tam tersidir. Bu yapıda ise koşul sağlandığı müddetçe döngü işletilmeye devam eder.Bu sebeple yukarıdaki kodda koşul cümlesini ters yazdım (yani I < 100 yerine I >100)

Döngüler ile ilgili örnek program :

Döngüler hakkında biraz daha geniş bilgiye sahip olmak için Loops adında örnek bir program yapalım. Loops programı sabit veya rastgele sayılardan oluşan bir sayaca sahip döngünün nasıl işlediğini göstermekte. Delphi program geliştirme ortamı içerisinde yeni bir proje başlatın adınıda Loops koyalım. Daha sonra aşağıdaki text olarak verilmiş form yapısını oluşturun.

object Form1: TForm1 Caption = 'Loops' object ListBox1: TListBox ... object BtnFor: TButton Caption = '&For' OnClick = BtnForClick end object BtnWhile: TButton Caption = '&While' OnClick = BtnWhileClick endend

Şekil 5.2

Page 33: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Form üzerindeki butonlardan üzerinde FOR yazana basınca listenin 1 den 20 ye kadar olan ardışık sayılar ile dolduğunu göreceksiniz. Butona her basışınızda liste içerisindeki tüm elemanlar silinip tekrar 1 den 20 ye kadar yazılacaktır. Şimdide üzerinde FOR yazan butonun onClick olayına göz atalım, işte kodu :

procedure TForm1.BtnForClick(Sender: TObject);var I: Integer;begin ListBox1.Items.Clear; for I := 1 to 20 do Listbox1.Items.Add ('String ' + IntToStr (I));end;

Üzerinde WHILE yazan ikinci butonun onClick olayı ise öncekine göre biraz daha karmaşık. 0 ile 99 arasında rastgele sayı üretilip listeye ekleniyor ve bu sayıların toplamı ne zaman 1000 in üzerine çıkarsa döngü işlevini tamamlamış oluyor. Programın koduna göz atalım

procedure TForm1.BtnWhileClick(Sender: TObject);var I: Integer;begin ListBox1.Items.Clear; Randomize; I := 0; while I < 1000 do begin I := I + Random (100); Listbox1.Items.Add ('Random Number: ' + IntToStr (I)); end;end;

    Burada bahsetmekte fayda gördüğüm iki komut var : Randomize ve Random komutları.

      Random komutunun kullanımı Random(x) şeklindedir ve 0 ile X-1 arasında rastgele değerler üretir, peki Randomize komutu ne işe yarar. Bunu anlamak için komutun başına // karakterlerini koyarak yorum cümlesi haline getirin böylece Delphi bu satırı işletmeyecektir. Daha sonra programı çalıştırıp WHILE yazan butona basın. Diyelimki 1,12,90,2,34 …. Sırasında sayılar üretti ve listeye ekledi. Butona ikinci basışınızda dikkat ederseniz yine aynı sayıları ürettiğini görceksiniz. Programdan çıkıp tekrar çalıştırın ve tekrar WHILE yazan butona basın bu sefer farklı sayılar gelecektir fakat programdan çıkmadan tekrar tekrar WHILE butonuna basdığınızda göreceksinizki hep aynı sayıları üretmekde. İşte dikkat edilmesi gereken nokta bu. Randomize komutu Random komutu ile üretilecek olan sayılar için Sistem saatine bağlı olarak bir referans noktası oluşturur. Saat sürekli değiştiği için Randomize komutunu işlettiğinizde bu referans noktasıda değişir, böylece programa girip çıkmadan sürekli farklı sırada sayılar üretebilirsiniz. Prgramın ekran çıktısı şöyle :

Page 34: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

NOT: Burada bahsetmek istediğim dört tane daha yeni komut bulunmakta bunlardan ilk ikisi Break ve Continue. Bu iki komuttan ilki içerisindebulunan döngüden çıkmaya yarar. Yani döngünün bittiği yerden sonraki komut işletilmeye başlanır. Continue ise yine döngü içersinde bulunulan yerden döngünün başına dönülmesini sağlar. Ve döngü "sayacın kaldığı yer" den devam ederek işletilir. Diğer iki komut ise Halt ve exit. Halt komutu işletildiği an programdan çıkılır. Yani program son bulur. Pek sağlıklı bir komut değildir çünkü hafızada bulunan nesnelerin onDestroy gibi olayları işletilmeden program sonlanır böylece program bitmesine rağmen hafızada hala yer iişgal edilir. Exit komutu ise içerisinde bulunulan fonksiyon yada prosedürden çıkılmasını sağlar. Yani Exit komut işletildiği an prosedüreden çıkılır.

With Statement :

   Son olarakta sadece Delphi diline mahsus olan bir komuttan bahsedeceğim. (Sanırım with yada benzeri bir komut Visual Basic dilinin yeni versiyonundada kullanılmaya başlandı)

With komutu daha az kod yazmaya yardımcı olmasının dışında bir işe yaramaz. Eğer bir Record yapısının yada bir nesnenin elemanlarına referans vermeniz gerekirse her seferinde o nesnenin yada recordun ismini yazmanıza gerek kalmaz. Örneğin :

type Date = record Year: Integer; Month: Byte; Day: Byte; end;

var BirthDay: Date;

begin BirthDay.Year := 1997; BirthDay.Month := 2;

Page 35: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

BirthDay.Day := 14;

Yukarıdaki kod yerine With statement'ını kullanarak şöyle yazabiliriz:

begin with BirthDay do begin Year := 1995; Month := 2; Day := 14; end;

Bu yaklaşımı bileşenlerde yada diğer Class (sınıf) tiplerindede kullanabilirsiniz. Örneğin Loop adındaki son örneği aşağıdaki gibi yazabiliriz.

procedure TForm1.WhileButtonClick(Sender: TObject);var I: Integer;begin with ListBox1.Items do begin Clear; // shortcut Randomize; I := 0; while I < 1000 do begin I := I + Random (100); // shortcut: Add ('Random Number: ' + IntToStr (I)); end; end;end;

Bazen bileşenlerle çalışırken iç içe yuvalanmış alanları yamaktanda kurtarır. Örneğin :

Form1.Canvas.Pen.Width := 2;Form1.Canvas.Pen.Color := clRed;//Yukarıdaki kod yerine şöyle yazılabilirwith Form1.Canvas.Pen dobegin Width := 2; Color := clRed;end;

With statement'ının sağladığı kolaylıkların yanında kullanırken dikkat edilmesi gereken noktalarda vardır örneğin aşağıdaki kod ile bir buttonun genişliğini, caption'ını, ve rengini değiştirelim (buton bileşeninin renk özelliğinin olmadığını hatırlatırım)

with Button1 dobegin Width := 200; Caption := 'New Caption'; Color := clRed;end;

Buton bileşeninin Color özelliği olmamasına rağmen derleyici hata vermez çünkü Formun color özelliği bulunmakta. Buton bileşeninde böyle bir özellik bulamayınca Formunkini değiştirecektir.

Page 36: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Fakat aynı kodu WITH statement'ını kullanmadan yazsaydık derleyicden hata uyarısını alacktık.

Button1.Width := 200;Button1.Caption := 'New Caption';Button1.Color := clRed; // HATA!

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 alternatififunction 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;

Page 37: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

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;

Page 38: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

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ştirilmekisteniyorend;

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 :

Page 39: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

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]);

Page 40: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

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; // caseend;

Page 41: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

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.

Page 42: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

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:

Page 43: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

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.

Page 44: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Ş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;

Page 45: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

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 :

Page 46: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

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

Page 47: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

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.

Bölüm 7 : String İşlemleri

Delphi ile string(karakter katarı, dizisi vs.) işlemleri yapmak çok kolaydır, fakat perde arkasındaki durum daha karmaşıktır. Pascalın geleneksel bir string işleme yapısı bulunmaktadır.Windowsun C dilinden aldığı kendine ait bir yapısı, 32bit Delphinin ise varsayım olarak kullandığı çok güçlü uzun string veri tipleri bulunmaktadır.

String Tipleri:

Borlandın Pascalı ile 16bitlik Delphide string veri tipi sıralı bir karakter dizisi ve bu karakter dizisinin başında dizinin uzunluğunu belirten bir bytelık alan bulunmaktaydı. Dizinin uzunluğunu belirtmeye yarayan alan bir byte tan oluştuğu için dizinin maximum uzunluğu 255 karakterden oluşmaktaydı buda önemli sorunlar yaratmaktaydı. Her string tipi standard olarak 255 karakter uzunluğunda yaratılmaktaydı, fakat kullanıcı isteğe bağlı olarak daha kısa stringler yaratıp hafızadan yer kazanabilmekteydi.

String tipi dizi tipine benzemektedir, tek fark stringin karakterlerden oluşan bir dizi olmasıdır. Buda string veri tipinin herhangi bir karakterine [] parantez işaretlerini kullanarak erişebileceğimiz anlamına gelmektedir.

Geneleneksel Pascal stringlerinin yarattığı kısıtlamalardan kurtulmak için 32bitlik Delphi sürümü daha uzun string yapılarını desteklemetedir. Gerçekte 3 değişik tipde string yapısı bulunmakta :

o ShortString tipi geleneksel Pascaldaki string ve 16bitlik Delphi sürümündeki string

veri tipi ile özdeştir. ShortString tipinin her bir elemanı ANSIChar veri tipinden oluşmaktadır.

o ANSIString veri tipi yeni değişken uzunluktaki string veri tipine karşılık gelmektedir. Bu stringler dinamik olarak yer kapladıkları gibi referans sayacı ve copy-on-write tekniğinide kullanırlar.Boyut olarak bu string tipi sınırlı değildir. 2 milyar karakter boyutlarında olabilir. Bu dizinin elemanlarıda ANSIChar tipinden oluşmaktadır.

o WideString veri tipide ANSIString veri tipi ile aynı özelliğe sahiptir fakat WideChar tipinde elemanlardan oluşmaktadır bu sebeple Unicode karakterleride saklayabilirler.

Uzun String Yapılarının kullanımı:

Eğer string veri tipini kullanıyorsanız $H derleyici direktifinin durumuna bağlı olarak ShortString yada ANSI string tipinde çalışırsınız. Delphi Bileşen kütüphanesininde varsayım olarak kullandığı yapı budur.

Delphinin LongStringleri temel olarak referans sayacı mekanizmasını kullanırlar. Bu mekanizma kaç tane string değişkeninin hafızadaki bir string yapısını referans olarak gösterdiğinin sayısını tutar. Ayrıca bu referans sayaç sistemi string lerin kullanılmamaları durumunda yani sayacın 0 olduğu durumlarda hafızadan silinmesini sağlar.Eğer string yapınızın boyutunu dinamik olarak arttırmak istediğinizde ve hafızada daha önce var olan stringinize komşu olan hafıza alanında başka bir bilgi varsa genişleme olmaz, bunun yerine var olan stringiniz hafızada daha geniş bir alana kopyalanır ve o alanda genişletilir.

Page 48: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Böyle bir durumda Delphinin çalışma kipi desteği btün bu işleri sizin yerinize transparan olarak yapar. Bir stringin ihtiyacınıza bağlı olarak maximum boyutunu SetLength prosedürünü kullanarak yapabilirsiniz.

SetLength (String1, 200);

Setlengthprosedürü gerçektende istenilen miktarda hafıza alanını ayırmaz sadece istekte bulunur, ve olanı ileride kullanılmak üzere rezerve eder.

String boyutunu ayarlamak çok seyrek olarak gereklidir.Uzunu stringler için boyut belirlemeniz gereken tek durum Windows apilerini kullandığınız durumlardır.Bu konuda kısa bir bilgi ileriki bölümlerde verilecektir.

Stringlerin hafızadaki durumları

Stringlerin hafızada nasıl yönetildiğini görebilmeniz için StrRef adında örneği hazırladım.Bu programda iki global string değişkeni tanımladım. İki butondan ilkine basılınca program birinci değişkene bir değer atıyor ve bu birinci değişkenide ikinci değişkene atıyor.

Str1 := 'Hello';Str2 := Str1;

Stringler ile çalışmanın yanında program bu değşikenlerin yerel durumlarını bir listbox içerisinde gösteriyor. Bu işlem içinde StringStatus fonksiyonunu kullnıyor:

function StringStatus (const Str: string): string;begin Result := 'Address: ' + IntToStr (Integer (Str)) + ', Length: ' + IntToStr (Length (Str)) + ', References: ' + IntToStr (PInteger (Integer (Str) - 8)^) + ', Value: ' + Str;end;

StringStatus fonksiyonunda hayati rol oynayan kod parametre olarak geçilen string değerinin const(sabit) olarak atanması.Bu parametreyi kopyalanması tekniğini (önceki bölümde parametrelerin nasıl aktarıldığını işlemiştik) kullansaydık string değişkeninin referans ettiği noktayı bulmakta zorlanacaktık. Bunun yanında parametreyi (var) ile referans olarak atamak veya (const) ile sabit olarak atmak bir sorun çıkarmayacaktır.

Bu durumda const kullandım çünkü fonksiyon içerisinde gelen parametrenin değerini değiştirecek bir işlem yapmayacağım.

String değişkeninin hafızada bulunduğu adresi elde etmek için ileri düzey typecast (tip dönüşüm) işlemleri gerçekleştirdim. Bundaki amacım bir string değişkeninin nasıl gösterildiğinive iki değişkenin aynı stringe nasıl referans gösterdiğini anlatmak.

Stringler aslında bir refereanstır, bir işaretçi, bir belirteçtir (Pointer). Bu değer, bu pointer stringing gerçek yerinin adresini tutar. Bu değişkene yapılan referans sayısını belirtmek için stringin içerisinde zaten tutulan bu değerleri okudum bunun için stringin başladığı adresten bazı değerleri matematiksel olarak çıkardım. -4 stringin uzunluğu için -8 ise yapılan referans sayısı için çıkarılır.

İleride Delphinin yeni versiyonları çıktığında bu değerlerinde değişebileceği gözden kaçırılmamalı. Bu örnek programı çalıştırdığınızda şekil 2.1 dede görüleceği üzere referans sayısının 2 olduğunu ve değişkenlerin aynı hafıza adreslerini kullandığını göreceksiniz.

Page 49: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Bu örnekteki iki değişkenin aynı hafıza adresine referansta bulunduğunu gördük. Bu durumda referansta bulunana iki değişkenden herhangi birisinde bir değişiklik yaptığınızda bu hafıza adresinin değiştiğini göreceksiniz.Copy-On-Write tekniğinin bir etkisi olarak görülmekte.

Yukarıda bahsedilen etkiyi oluşturmak için şekil 7.1 de gösterilen form üzerindeki Change yazılı butonun onClick olayına aşağıdaki kodu yazmamız yeterli olacaktır.

procedure TFormStrRef.BtnChangeClick(Sender: TObject);begin Str1 [2] := 'a'; ListBox1.Items.Add ('Str1 [2] := ''a'''); ListBox1.Items.Add ('Str1 - ' + StringStatus (Str1)); ListBox1.Items.Add ('Str2 - ' + StringStatus (Str2));end;

Change butonuna basıldığında tepki gösterilmesi için Assign butununa basılmış olması gerekmektedir. Bu tür bir kısıtlamanın oluşturulabilmesi için form aktif olduğu sırada Change butonunun etkin olma öelliğinin false hale getirilmesi gerekir. (Yani object inspector penceresinden Enabled özelliğinin False yapılması gerekir.) Bu örnekte bulunan StringStatus fonksiyonunda değişiklikler yaparak LongString lerin yapıları ve durumları hakkındada bilgi edinebilirsiniz.

Delphi'deki Stringler ve Windows'daki PChars'lar

LongStringlerin kullanımında dikkat edilmesi gereken önemli diğer bir noktada Bu stringlerin Null-Terminated olmasıdır. Yani bu stringlerin son karakterlerinden sonra bir başka karakterin NULL karakterinin bulunmasıdır. Neden önemli olduğuna gelirsek bu yapının C programlama dilinde ve Windowsun temelinde kullanılan string yapısıyla özdeş olmasıdır. Bir nevi uyumluluk sağlamaktadır. Pascaldaki LongStringler null-terminated olduğu için C dilindeki null-terminated stringlerle uyum sağlar bu nedenle LongStringleri casting işlemine tabii tutarak WindowsAPI çağrılarına parametre olarak geçebilirsiniz. Örneğin Windowsun API çağrılarını kullanarak formun Caption'ını PChar tipinde bir string e atayıp daha sonra bu Captionu bir butonun Caption özelliğine aktaralım. Program kodu aşağıdaki gibi olacaktır :

procedure TForm1.Button1Click (Sender: TObject);var S1: String;begin SetLength (S1, 100); GetWindowText (Handle, PChar (S1), Length (S1)); Button1.Caption := S1;end;

Page 50: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

Bu kodu LongString örneğinde bulabilirsiniz. Burada dikkat etmeniz gereken nokta SetLength komutunu kullanmadan API çağrısında bulunduğunuzda programınızın çökeceğidir. Eğer PChar tipinde ir değişken kullansaydınız program kodu daha basitleşecekti çünkü bu iş için geçici bir string değişken tanımlamamış ve değişkeni initialize (ilk kullanıma hazırlama) etmemiş olacaktınız. Aşağıdaki kod Label bileşeninin caption özelliğini API çağrısına parametre olarak geçmektedir.

SetWindowText (Handle, PChar (Label1.Caption));

Eğer WideString tipini Windows uyumlu bir tipe çevirmek isterseniz PChar yerine PWideChar tipini kullanabilirsiniz. WideStringler (widechar) OLE ve COM programlarında kullanılmaktadırlar.

Bu noktaya kadar oluşturulan izlenimden sonra karşılaşılabilecek tuzaklara odaklanmak istiyorum. LongString yapısının PChar yapısına dönüştürülmesi sırasında bazı problemlerle karşılaşılabilir. Yani dönüşüm yaptıkdan sonra bütün sorumluluk size kalır Delphi bu noktadan sonra yeni yapının içeriği ve durumu ile ilgilenmez. Yukarıdaki program kodu parçasına yapılan ufak değişklilerden sonra oluşturulan aşağıdaki yeni koda dikkat ediniz :

procedure TForm1.Button2Click(Sender: TObject);var S1: String;begin SetLength (S1, 100); GetWindowText (Handle, PChar (S1), Length (S1)); S1 := 'Başlık = ' + S1; // bu kod işe yaramayacaktır. Button1.Caption := S1;end;

Yukarıdaki kod derlenir fakat çalıştırdığınızda beklediğinizden farklı bir sonuç elde edersiniz. Buton'un Caption özelliği sizin eklemiş olduğunuz text değilde pencerenin orjinal text özelliğini gösterir. Bu sorunun sebebi, windows string değişkenine birşeyler yazdığı zaman o stringin uzunluğunu tam olarak ayarlayamaz. Delphi bu stringi yinede kullanabilir fakat null karakterini gördüğü noktada duracaktır ve geri kalan karakterleri gözardı edecektir. Bu problemi nasıl çözebiliriz?

Bunun için sisteme GetWindowText API fonksiyonun geriye dönderdiği stringi Pascal stringine çevirmesini söylememiz gerekmektedir. Hernekadarda aşağıdaki kodu yazsanız çalışmayacaktır.

S1 := String (S1);

Sistem bunuda gözardı edecektir, çünkü bir veri tipini tekrar aynı veri tipine çevirmek faydasız bir işlemdir. Uygun Pascal stringini elde edebilmek için stringi pchar'a cast edip daha sonra tekrar stringe çevirmektir.

S1 := String (PChar (S1));

Aslında bu uyarlama işinide atlayabilirsiniz. Pchardan Stringe dönüştürme işlemini Delphi otomatik olarak yapar. İşte son kodun son hali:

procedure TForm1.Button3Click(Sender: TObject);var S1: String;begin SetLength (S1, 100); GetWindowText (Handle, PChar (S1), Length (S1)); S1 := String (PChar (S1)); S1 := S1 + ' is the title'; Button3.Caption := S1;

Page 51: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

end;

Alternatif diğer bir çözümde Delphi stringinin uzunluğunu Pchar stringinin uzunluğuna eşitlemektir. Bu işlem için aşağıdaki kodu kullanırız:

SetLength (S1, StrLen (PChar (S1)));

Stringleri Formatlamak

(+) operatörü ve bazı dönüşüm fonksiyonlarını ( IntToStr gibi ) kullanarak mevcut değerlerden karmaşık stringler elde edebilirsiniz. Bununla birlikte sayıları, parasal değerleri ve diğer strinleri tek bir string olarak elde edebilirsiniz. Bu iş için çok güçlü Format fonksiyonu yada türevlerini kullanabilirsiniz.Format fonksiyonu bir dizi parametre almaktadır. Bunlardan birincisi diğer verilerin içerisinide hangi noktalara yerleştirilmesi gerektiğini belirten temel string'tir. İkincisi ise yerleştirilmesini istediğimiz veri dizisidir. Örneğin iki sayıyı bir string yapısı içersinde formatlamak için şu kodu kullanırız :

Format ('First %d, Second %d', [n1, n2]);

n1 ve n2 integer değerlerdir. İlk %d ifadesi yerine dizideki ilk değer, ikinci %d ifadesi yerine dizideki ikinci değer koyulur. Yüzde işaretinden sonra kullandığımız karakter bu alana ne tür bir değerin koyulacağını belirtir. %d integer değerleri yerleştirmek için kullanılır. %d yazıpta veri dizisi içerisine string bir ifade yerleştirdiğimizde kod derlenir fakat çalıştırıldığında Run-Time Error alırsınız. Format fonksiyonunu kullanmanın tek dezavantajıda budur. Yani derleme esnasında tip uyumluluğu kontrolü yapılmaz.

Format fonksiyonu parametre olarak bu bölümün sonuda anlatacağımız açık dizi yapısını kullanır. Yani farklı tiplerde değerleri parametre olarak alabilir.

%d ifadesi yerine kullanabileceğiniz alternatif değerler aşağıdaki tabloda verilmiştir.

Tip belirteci Tanım

d (decimal) Ondalık İlgili Integer değer ondalık sayı olarak stringe çevirilir

x (hexadecimal) Onaltılık

İlgili Integer değer onaltılık sayı siteminde stringe çevirilir

p (pointer) İlgili pointer değeri onaltılık siteme göre stringe çevirilir.

s (string) İlgili Pchar yada string değeri tekrar string olarak temel stringe yerleştirilir.

E (exponential) İlgili exponansiyel değer stringe çevirilir.

f (floating point) İlgili Integer değer ondalık sayı olarak stringe çevirilir.

G (general) The corresponding floating-point value is converted to the shortest possible decimal string using either floating-point or exponential notation.

N (number) İlgili kayan noktalı sayılar ondalık sayı olarak stringe çevirilir ve bindelik hanelere ayırılır

M (money) The corresponding floating-point value is converted to a string representing a currency amount. The conversion is based on regional settings-see the Delphi Help file

Page 52: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

under Currency and date/time formatting variables.

Bunun yanında sayıların kaç hanede temsil edileceğini ve ondalık sayıların ondalık kısımlarının kaç basamak olacağınıda belirleyebilirsiniz. Örneğin :

Format ('%8d', [n1]);

Bütün bu formatlama işlemlerini daha iyi incelemek için frmTest adlı programı yazdım. Aşağıda örnek bir çıktısı ile kodunu göreceksiniz:

procedure TFormFmtTest.BtnIntClick(Sender: TObject);begin ShowMessage (Format (EditFmtInt.Text, [StrToInt (EditInt.Text)])); // if the item is not there, add it if ListBoxInt.Items.IndexOf (EditFmtInt.Text) < 0 then ListBoxInt.Items.Add (EditFmtInt.Text);end;procedure TFormFmtTest.ListBoxIntClick(Sender: TObject);begin EditFmtInt.Text := ListBoxInt.Items [ ListBoxInt.ItemIndex];end;

Dynamik Arrays (Dinamik diziler)

Geleneksel olarak Pascal dilinde dizi yapıları hep sabit boyuttadır. Dizi veri tipinde bir yapı tanımladığınızda bu dizinin boyutunuda belirlemeniz gerekir. Uzman kullanıcılar tarafından bilinen bir kaç tane dinamik dizi yapıları tanımlamanın yolları vardır. Tipik olarak pointer kullanıp gerekli hafıza reservasyonunun ayırmak yada tekrar sisteme bırakmak gibi.

Delphi 4 kullanımı çok kolay olan dinamik dizi tanımlama eklentileri ile nirlikte gelmektedir. Dinamik dizi yapılarından "Long Stringler" dinamik olarak sistemden gerekli hafıza alanını temin ederler fakat copy-on-write tekniğini kullanmazlar. ( Copy-on-write : Diyelimki 500 karakterlik A ve B adında iki karakter dizisi değişkeniniz var. başta ikiside aynı bilgileri gösteriyor olsun. İşte böyle birdurumda hafızadan 500 karakterlik yer ayrılır 1000 değil ve iki değişkende aynı yeri gösterir. Fakat A değişkeninin herhangi bir karakterinde değişiklik yaptığınız anda a değişkeni hafızadan diğer 500 lük yeri ayırır ve değişime uğramış halini o alana kopyalar. Kısaca değişiklik yapılmadan önce hafızadan 500 lük alan tahsis edilmişti ama herhangi birisindeki değişiklikten sonra ikinci bir 500 lük yer ayırılır. Zaten olması gerekende budur.) aslında bu büyük bir sorun değildir bir değişkenin sistemden aldığı hafıza alanını, o değişkene NIL atayarak tekrar sisteme kazandırabilirsiniz.

Artık belli bir boyut belirtmenden bir dizi tanımlayıp daha sonra bu diziyi SETLENGTH prosedürünü kullanrak istediğiniz şekilde boyutlandırabilirsiniz. Aynı prosedüre içerisinde bilginin mevcut olduğu bir dizide bilgiyi kaybetmeyecek şekildede kullanılabilir. Bunun yanında string yapılarına özgü COPY gibi başka fonksiyonlarda bulunmaktadır.

İşte size küçük bir kod alıntısı. Altını çizerek belirtmeliyimki dizi değişkenini tanımladıktan sonra kullanmadan önce boyutlarını belirtmelisiniz.

procedure TForm1.Button1Click(Sender: TObject);var  Array1: array of Integer;begin

Page 53: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

  Array1 [1] := 100; // hata  SetLength (Array1, 100);  Array1 [99] := 100; // Tamam  ...end;

Genel Pascal dizileri 0 olmayan alt tabanlı ve integer olmayan indisleri kabul etmezler. İşte dinamik dizilerin uymadığı kurallarda bunlardır. Yani 100 lük bir dinamik dizinin alt sınırı 0 üst sınırı 99 dur.

Dinamik bir dizinin durumu hakkında bilgi edinmek için diğer dizilerde kullanılan Length, High, Low gibi fonkiyonları kullanabilirsiniz. Bununla birlikte dinamik dizilerde Low prosedürü 0 geriye döndürürken High da dizinin uzunluğunun bir eksiğini geriye dönderir. Boş bir dizi için ilginçtirki low 0, high -1 geriye dönderir.

Şekil : 8.1 DynArr örneğinin bir çıktısı.

Bütün bu kısa tanıtımdan sonra DynArr adındaki basit bir örneği sizlere gösterebilirim. Bu gerçektende basit bir örnek zira karmaşık dinamik dizi yapıları bulunmamakta. Bu örneğin diğer bir amacıda programcıların yapabileceği olası hataları göstermek.

Program iki tane global dizi tanımlamakta ve bunlardan birincisini OnCreate tutamacında kullanıma hazırlamaktadır.

var  Array1, Array2: array of Integer;

procedure TForm1.FormCreate(Sender: TObject);begin  // sistemden gerekli hafızayı ayırt  SetLength (Array1, 100);end;

Yukarıdaki kod bütün değerleri 0 olarak tanımlamaktadır. Bu başlangış kodu herhangi bir hafıza hatasına yer vermeden diziyi kullanıma hazırlamaktadır. Daha iyi bir sıfırlama işlemi için dizinin bütün elemanlarının içeriğini değiştiren butonun kodu aşağıdaki gibidir :

procedure TForm1.btnFillClick(Sender: TObject);var  I: Integer;begin  for I := Low (Array1) to High (Array1) do    Array1 [I] := I;end;

Grow adındaki düğme dizinin içeriğini kaybetmede boyutlarını büyütmek için kullanılır. Bunu Grow düğmesine bastıktan sonra Get düğmesine basarak test edebilirsiniz.

procedure TForm1.btnGrowClick(Sender: TObject);begin

Page 54: BÖLÜM 1 : PASCAL'IN TARIHÇESI · Web viewEğer subrange olarak 1..3 alrsak bu kümenin alacağ değerler sadece 1, sadece 2, sadece 3, 1 ve 2, 1 ve 3 , 2 ve 3, hepsi yada hiçbiri

  // grow keeping existing values  SetLength (Array1, 200);end;

procedure TForm1.btnGetClick(Sender: TObject);begin  // extract  Caption := IntToStr (Array1 [99]);end;

Tek karmaşık olan kod Alias düğmesinin OnClick olayında bulunmakta. Program := operatörünü kullanarak dizilerden birisini diğerine kopyalar. Bu noktadan sonra dizilerden birisinde değişiklik yaptığınızda diğeride etkilenir. Çünkü ikiside aynı hafıza alanını göstemektedir.

procedure TForm1.btnAliasClick(Sender: TObject);begin  // alias  Array2 := Array1;  // change one (both change)  Array2 [99] := 1000;  // show the other  Caption := IntToStr (Array1 [99]);

BtnAliasClick metodu iki tane dahaişlem gerçekleştirmektedir. İlki dizilerin eşitliğini test eder. Bu test dizilerin gerçek elemanlarını değilde dizilerin gösteridiği hafıza alanlarını kontrol eder.

procedure TForm1.btnAliasClick(Sender: TObject);begin  ...  if Array1 = Array2 then    Beep;  // truncate first array  Array1 := Copy (Array2, 0, 10);end;

ikincisi ise Copy fonksiyonuna yapılan çağrıdır. Bu fonksiyon verileri bir diziden diğerine taşımanın ötesinde ilk diziyi fonksiyon tarafından yaratılan yenisiyle değiştirir. Bu sebeple Array1 değişkeni düğmeye basıldıktan sonra 11 elemanlı bir diziyi gösterir. Bu sebeple Get yada Set düğmelerinden birine basılınca hafıza hatası üretilir ve bir exception çıkarılır. Fill butonunun kodu bu değişiklikten sonrada işe yarar çünkü dizinin boyutları için Low ve High fonksiyonu kullanılmıştır.