|
|
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 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. 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; 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: 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 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; 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 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 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 Sabit bir Karakter dizisi tanimlarken yukaridaki gibi bir tanim yapacaginiza Delphi 3 ile birlikte su tanimi yapabilirsiniz :
resourcestring 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
procedure TForm1.Button1Click(Sender: TObject); 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: 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.
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. 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 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); 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.
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:
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. 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 Seklinde tanimlanmistir. TDateTime’in kullanimi oldukça basittir, çünkü Delphi bu veri tipi için asagidaki tabloda bulunan fonksiyonlari tanimlamistir.
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); ilk komut Now fonksiyonunu çagirmakta ve o anki tarih ve saati StartTime adindaki global degiskende saklamaktadir.
var
FormTimeNow: TFormTimeNow; Ben sadece ikinci tanimlamayi ekledim birincisi Delphi terafindan saglandi.
var 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); 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; 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.
type 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 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.
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). Str Converts a number into a string, using formatting parameters (traditional Turbo Pascal routine, available for compatibility). StrPas Converts 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.) StrPCopy Copies 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. StrToFloat Converts the given Pascal string to a floating-point value. TextToFloat Converts the given null-terminated string to a floating-point value. |