|
#1
| ||||
| ||||
| *** C anlatımı *** " Bölüm 4 ve 5 " 4. BÖLÜM : VERİ TÜRLERİ Nesne (Object) kavramını incelediğimiz zaman, nesnelerin en önemli özelliklerinden birinin nesnenin türü olduğunu belirtmiştik. Tür (type) nesnenin olmazsa olmaz bir özelliğidir ve türü olmayan bir nesneden söz etmek mümkün değildir. Derleyiciler nesnelerle ve verilerle ilgili kod üretirken, tür bilgisinden faydalanırlar. Tür bilgisinden, söz konusu veriyi bellekte ne şekilde tutacaklarını, verinin değerini ne şekilde yorumlayacaklarını, veriyi hangi işlemlere tabi tutabileceklerini öğrenirler. Programlama dilleri açısından baktığımız zaman türleri iki ayrı gruba ayırabiliriz. 1. Önceden tanımlanmış veri türleri (Doğal veri türleri) (Basic tpes, default types, built-in types, primitive types) Programlama dilinin tasarımından kaynaklanan ve dilin kurallarına göre varlığı garanti altına alınmış olan türlerdir. Her programlama dili programcının doğrudan kullanabileceği, çeşitli özelliklere sahip veri türleri tanımlar. C dilinde de önceden tanımlanmış 11 adet veri türü vardır. 2. Programcının tanımlanmış olduğu veri türleri (user defined types) Programlama dillerinin çoğu, önceden tanımlanmış veri türlerine ek olarak, programcının da yeni türler tanımlanmasına izin vermektedir. Programcının tanımlayacağı bir nesne için önceden tanımlanmış veri türleri yetersiz kalıyorsa, programcı kendi veri türünü yaratabilir. C dilinde de programcı yeni bir veri türünü derleyiciye tanıtabilir ve tanıttığı veri türünden nesneler tanımlayabilir. Farklı programlama dillerindeki önceden tanımlanan veri türleri birbirlerinden farklı olabilir. Daha önce öğrenmiş olduğunuz bir programlama dilindeki türlerin aynısını C dilinde bulamayabilirsiniz. C dilininin önceden tanımlanmış 11 veri türü vardır. Bu veri türlerinden 8 tanesi tamsayı türünden verileri tutmak için, kalan 3 tanesi ise gerçek sayı türünden verileri tutmak için tasarlanmıştır. Biz bu türlere sırasıyla "Tamsayı veri türleri" (integer types) ve "gerçek sayı veri türleri" (floating types) diyeceğiz. tamsayı veri türleri (integer types) C dilinin toplam 4 ayrı tamsayı veri türü vardır ancak her birinin kendi içinde işaretli ve işaretsiz biçimi olduğundan, toplam tamsayı türü 8 kabul edilir. İşaretli (signed) tamsayı türlerinde pozitif ve negatif tam sayı değerleri tutulabilirken, işaretsiz (unsigned) veri türlerinde negatif tamsayı değerleri tutulamaz. Bu türleri sırasıyla inceleyelim: işaretli ve işaretsiz char veri türü : Şüphesiz char sözcüğü ingilizce character sözcüğünden kısaltılmıştır ve türkçe "karakter" anlamına gelmektedir. Ancak bu türün ismini, bundan sonraki derste C dilinin bir anahtar sözcüğü olduğunu öğreneceğimiz char sözcüğü ile özdeşleştirip, "char türü" (çar diye okuyunuz) diye söyleyeceğiz. İşaretli char türünden bir nesnenin bir byte'lık bir alanda tutulması C standartlarınca garanti altına alınmıştır. 1 byte'lık bir alanı işaretli olarak kullandığımızda yazabileceğimiz değerlerin -128 / 127 değerleri arasında değişebileceğini sayı sistemleri dersimizden hatırlayalım. işaretsiz char veri türünün işaretli olandan farkı 1 byte'lık alanın işaretsiz olarak, yani yalnızca 0 ve pozitif sayıların ifadesi için kullanılmasıdır. Bu durumda işaretsiz char türünde 0 - 255 arasındaki tamsayı değerleri tutulabilir. işaretli ve işaretsiz short int veri türü (işaretli kısa tamsayı türü - işaretsiz kısa tamsayı türü) : Yine bundan sonraki derste öğreneceğimiz gibi, short ve int sözcükleri C dilinin anahtar sözcüklerinden olduğu için bu türün ismini genellikle short int, ya da kısaca short türü olarak telaffuz edeceğiz. işaretli ve işaretsiz short veri türünden bir nesne tanımlandığı zaman, nesnenin bellekte kaç byte yer kaplayacağı sistemden sisteme değişebilir. Sistemlerin çoğunda, short int veri türünden yaratılan nesne bellekte 2 byte'lık bir alan kaplayacaktır. işaretli short int veri türünden bir nesne -32768 - +32767 aralığındaki tamsayı değerlerini tutabilirken, işaretsiz short türü söz konusu olduğıundan tutulabilecek değerler 0 - +65535 aralığında olabilir. işaretli int (signed int) türü ve işaretsiz int (unsigned int) türü : işaretli ve işaretsiz int veri türünden bir nesne tanımlandığı zaman, nesnenin bellekte kaç byte yer kaplayacağı sistemden sisteme değişebilir. Çoğunlukla 16 bitlik sistemlerde, int veri , 32 bitlik sistemlerde ise int veri türü 4 byte yer kaplamaktadır. 16 bitlik sistem, 32 bitlik sistem ne anlama geliyor. 16 bitlik sistem demekle işlemcinin yazmaç (register) uzunluğunun 16 bit oldugunu anlatıyoruz. int veri türünün 2 byte uzunluğunda olduğu sistemlerde bu veri türünün sayı sınırları, işaretli int türü için -32768 - +32767, işaretsiz int veri türü için 0 - +65535 arasında olacaktır. işaretli ve işaretsiz long int veri türü (işaretli uzun tamsayı türü - işaretsiz uzun tamsayı türü) Bu türün ismini genellikle long int, ya da kısaca long türü olarak telaffuz edeceğiz. işaretli ve işaretsiz long int veri türünden biriyle tanımlanan bir nesnenin bellekte kaç byte yer kaplayacağı sistemden sisteme değişebilir. Sistemlerin çoğunda, long int veri türünden yaratılan nesne bellekte 4 byte'lık bir alan kaplayacaktır. İşaretli long int veri türünden bir nesne -2147483648 - +2147483647 aralığındaki tamsayı değerlerini tutabilirken, işaretsiz long int türü söz konusu olduğıundan tutulabilecek değerler 0 - +4.294.967.296 aralığında olur. GERÇEK SAYI TÜRLERİ C dilinde gerçek sayı değerlerini tutabilmek için 3 ayrı veri türü tanımlanmıştır. Bunlar sırasıyla, float, double ve long double veri türleridir. Gerçek sayı veri türlerinin hepsi işaretlidir. Yani gerçek sayı veri türleri içinde hem pozitif hem de negatif değerler tutulabilir. Gerçek sayıların bellekte tutulması sistemden sisteme değişebilen özellikler içerebilir. Ancak sistemlerin çoğunda IEEE 754 sayılı standarda uyukmaktadır. Sistemlerin hemen hemen hepsinde float veri türünden bir nesne tanımlandığı zaman bellekte 4 byte yer kaplayacaktır. 4 byte'lık yani 32 bitlik alana özel bir kodlama yapılarak gerçek sayı değeri tutulur. IEEE 754 sayılı standartta 4 byte'lık gerçek sayı formatı "single precision " (tek hassasiyet) olarak isimlendirilmiştir. Bu standartta 32 bitlik alan 3 bölüme ayrılmıştır. 1 bitlik alan (sign bit): gerçek sayının işaret bilgisini yani pzoitif mi negatif mi olduğu bilgisini tutar. 8 bitlik alan (exponential part) : 23 bitlik alan (fraction part) : sayının ondalık kısmını tutar. Sistemlerin hemen hemen hepsinde double veri türünden bir nesne tanımlandığı zaman bellekte 8 byte yer kaplayacaktır. Gerçek sayıların bellekte tutulması sistemden sisteme değişebilen özellikler içerebilir. Ancak sistemlerin çoğunda IEEE 754 sayılı standarda uyulmaktadır. long double veri türünden bir nesne tanımlandığı zaman bellekte 10 byte yer kaplayacaktır. ![]() #include <middleeast.h> #define ISRAELIS foul_beasts |
|
#2
| ||||
| ||||
| C dilinin doğal veri türlerine ilişkin bilgileri aşağıda bir tablo şeklinde veriyoruz: Yukarıda verilen tablo sistemlerin çoğu için geçerli de olsa ANSI C standartlarına göre yalnızca aşağıdaki özellikler garanti altına alınmıştır: char türü 1 byte uzunluğunda olmak zorundadır. short veri türünün uzunluğu int türünün uzunluğuna eşit ya da int türü uzunluğundan küçük olmalıdır. Yani short <= int long veri türünün uzunluğu int türüne eşit ya da int türünden büyük olmak zorundadır. Yani long >= int Derleyiciler genel olarak derlemeyi yapacakları sistemin özelliklerine göre int türünün uzunluğunu işlemcinin bir kelimesi kadar alırlar. 16 bitlik bir işlemci için yazılan tipik bir uygulamada char türü 1 byte int türü 2 byte (işlemcinin bir kelimesi kadar) short türü 2 byte (short = int) long türü 4 byte (long > int) alınabilir. Yine 32 bitlik bir işlemci için yazılan tipik bir uygulamada char türü 1 byte int türü 4 byte (işlemcinin bir kelimesi kadar) short türü 2 byte (short < int) long türü 4 byte (long = int) alınabilir. C dilinin en çok kullanılan veri türleri tamsaylar için int türü iken gerçek sayılar için double veri türüdür. Peki hangi durumlarda hangi veri türünü kullanmak gerekir. Bu sorunun cevabı olarak hazır bir reçete vermek pek mümkün değil, zira kullanacağımız bir nesne için tür seçerken bir çok faktör söz konusu olabilir, ama genel olarak şu bilgileri verebiliriz : Gerçek sayılarla yapılan işlemler tam sayılarla yapılan işlemlere göre çok daha fazla yavaştır. Bunun nedeni şüphesiz gerçek sayıların özel bir şekilde belirli bir byte alanına kodlanmasıdır. Tamsayıların kullanılmasının yeterli olduğu durumlarda bir gerçek sayı türünün kullanılması , çalışan programın hızının belirli ölçüde yavaşlatılması anlamına gelecektir. Bir tamsayı türünün yeterli olması durumunda gerçek sayı türünün kullanılması programın okunabilirliğininin de azalmasına neden olacaktır. ![]() #include <middleeast.h> #define ISRAELIS foul_beasts |
|
#3
| ||||
| ||||
| 5. BÖLÜM : BİLDİRİM VE TANIMLAMA Progamlama dillerinin çoğunda nesneler kullanılmadan önceye derleyiciye tanıtılırlar. Nesnelerin kullanılmalarından önce, özellikleri hakkında derleyiciye bilgi verme işlemlerine bildirim (declaration) denir. Bildirim işlemi yoluyla, derleyiciler nesnelerin hangi özelliklere sahip olduklarını anlarlar ve böylece bu nesneler için bellekte uygun bir yer tahsisatı yapabilirler. Yaratılacak nesne hakkında derleyiciye verilecek en önemli bilgi şüphesiz nesneye ilişkin tür (type) bilgisidir. C dilinde eğer yapılan bir bildirim işlemi, derleyicinin bellekte bir yer ayırmasına neden oluyorsa bu işleme tanımlama (definition) denir. Tanımlama nesne yaratan bir bildirimdir. Her tanımlama işlem aynı zamanda bir bildirim işlemidir ama her bildirim işlemi bir tanımlama olmayabilir. Başka bir deyişle, tanımlama nesne yaratan bir bildirim işlemidir. C dilinde bir değişkeni bildirimini yapmadan önce kullanmak derleme işleminde hata (error) oluşumuna yol açar. Bir değişkenin derleyiciye tanıtılması değişkenin türünün ve isminin derleyiciye bildirilmesidir ki, derleyici bu bilgiye dayanarak değişken için bellekte ne kadar yer ayıracağını, değişkenin için ayrılan byte'lardaki 1 ve 0 ların nasıl yorumlanacağı bilgisini elde eder. C Dilinde Bildirim İşleminin Genel Biçimi C programlama Dili'nde bildirim işlemi aşağıdaki şekilde yapılmaktadır : <tür> <nesne ismi> <;> Burada noktalı virgül karakterine sonlandırıcı karakter diyoruz. Noktalı virgül ayıraç türünden bir atomdur ve C'de bütün ifadeler noktalı virgül ile birbirlerinden ayrılırlar. a = x + 1; b = x + 2; ifadelerinde bulunan noktalı virgüller bunların ayrı birer ifade olduklarını gösterirler. Eğer bir tek noktalı virgül olsaydı derleyici iki ifadeyi tek bir ifade gibi yorumlayacaktı. a = x + 1 b = x + 2; Yukarıdaki ifade tek bir ifade gibi yorumlanır ve derleyici buna bir anlam veremez. Tür belirten anahtar sözcükler, C dilinin önceden tanımlanmış veri türlerine ilişkin anahtar sözcüklerdir. Bu sözcükleri bildirim sentaksında kullanarak, daha önce öğrenmiş olduğumuz 11 temel veri türünden hangisinden değişken tanımlamak istediğimizi derleyiciye bildirmiş oluyoruz. C dilinin önceden tanımlanmış veri türlerine ilişkin, bilidirim işleminde kullanılabilecek anahtar sözcükler şunlardır : signed, unsigned, char, short, int, long, float, double Bu sözcüklerin hepsi anahtar sözcük olduğundan küçük harf ile yazılmalıdır, C dilinin büyük harf küçük har duyarlı (case sensitive) bir dil olduğunu hatırlayalım. C dilinin tüm anahtar sözcükleri küçük harf ile tanımlanmıştır. Tür belirten anahtar sözcükler aşağıdaki tabloda listelenen seçeneklerden biri olmalıdır. Köşeli parantez içerisindeki ifadeler kullanılması zorunlu olmayan, yani seçime bağlı olan anahtar sözcükleri göstermektedir. Aynı satırdaki tür belirten anahtar sözcükler tamamen aynı anlamda kullanılabilmektedir. ![]() Yukarıdaki tablodan da görüldüğü gibi, belirli türleri birden fazla şekilde ifade etmek mümkündür. ![]() Yukarıda aynı kolon üzerindeki bildirimlerin hepsi aynı türden nesne yaratır. Bildirim işleminde nesne ismi olarak, C dilinin isimlendirme kurallarına uygun olarak seçilen herhangi bir isim kullanılabilir. C dilinde isimlendirilenler (identifiers) kavramı 6 grubu içerir. Değişkenler (variable) bunlardan yalnızca bir tanesidir. Fonksiyonlar (functions), etiketler (labels), makrolar (macros), yapı ve birlik isimleri (structure and union tags), enum sabitleri (enum constants) isimlerini programcılardan alırlar. C Dilinin İsimlendirme Kuralları İsimlendirmede yalnızca 63 karakter kullanılabilir. Bunlar: İngiliz alfabesinde yer alan 26 karakter, (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z) rakam karakterleri (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) ve alttire (underscore) karakteridir. (_) İsimlendirmelerde yukarıda belirtilen karakterlerin dışında başka bir karakterin kullanılması derleme zamanında hata oluşumuna yol açar. (ömeğin boşluk karakterinin kullanılması Türkçe karakterlerin kullanılması, +, -, /, *, & ya da $ karakterinin kullanılması gibi). Değişken isimleri rakam karakteriyle başlayamaz. Rakam karakteri dışında, yukarıda geçerli herhangi bir karakterle başlayabilir. C'nin anahtar sözcükleri isimlendirme amacı ile kullanılamaz. İsimler boşluk içeremeyeceği için uygulamalarda genellikle boşluk hissi vermek için alttire (underscore) karakteri kullanılır. genel_katsayi_farki, square_total, number_of_cards gibi. Başka bir teknik de isimlendirmede her sözcüğün ilk harfini Büyük, diğer harfleri küçük yazmaktır. GenelKatsayiFarki, SquareTotal, NumberOfCards gibi. C dilinde yapılan isimlendirmelerde, isimlerin maksimum uzunluğu tanımlanmamıştır. Bu derleyicilere göre değişebilir. Ancak bir çok derleyicide 32 sayısı kullanılmaktadır. Eğer verilen isim 32 karakterden daha fazla karakter içeriyorsa, derleyici bu ismi budar, yani yalnızca ilk 32 karakterini algılar. C dili büyük harf küçük harf duyarlığı olan bir dil olduğu için (case sensitive) isimlendirmelerde de büyük harf ve küçük harfler farklı karakterler olarak ele alınacaktır : var, Var, VAr, VAR, vAR, vaR değişkelerinin hepsi ayrı değişkenler olarak ele alınacaktır. Bu noktaların hepsi C dilinin sentaksı açısından, hata oluşumunu engellemek için zorunlu durumları belirtmek için anlatılmıştır. İsimlendirme yazılan programların okunabilirliği açısından da çok önemlidir. Kullanılan isimlerin legal olmalarının dışında, anlamlı olmalarına, kodu okuyacak kişiye bir fikir verecek şekilde seçilmelerine de dikkat edilmelidir. Bildirim işlemi noktalı virgül ile sonlandırılmalıdır. ![]() #include <middleeast.h> #define ISRAELIS foul_beasts |
|
#4
| ||||
| ||||
| Bildirim Örnekleri Kod: int x; unsigned long int var; double MFCS; unsigned _result; signed short total; Kod: unsigned char ch1, ch2, ch3, ch4; float FL1, Fl2; unsigned total, subtotal; int _vergi_katsayisi, vergi_matrahi; Kod: long x, int y; /* error */ signed ve unsigned sözcükleri tür belirten anahtar sözcük(ler) olmadan yalnız başlarına kullanılabilirler. Bu durumda int türden bir değişkenin bildiriminin yapıldığı kabul edilir: Kod: signed x, y; ile signed int x, y; tamamen aynı anlamdadır. Yine unsigned u; ile unsigned int u; Bildirim işleminde, tür belirten anahtar sözcük birden fazla ise bunların yazım sırası önemli değildir, ama okunabilirlik açısından önce işaret belirten anahtar sözcüğün sonra tip belirten anahtar sözcüğün kullanılması gelenek haline gelmiştir. Örneğin : Kod: signed long int x; signed int long x; long signed int x; long int signed x; int long signed x; int signed long x; Bildirimlerin Kaynak Kod İçinde Yapılış Yerleri C dilinde genel olarak 3 yerde bildirim yapılabilir : 1.Blokların içinde 2.Tüm blokların dışında. 3.Fonksiyon parametre değişkeni olarak fonksiyon parantezlerinin içerisinde Fonksiyon parametre parantezleri içerisinde yapılan bildirimler, başka bir sentaks kuralına uyarlar, bu bildirimler fonksiyonlar konusuna gelindiğinde detaylı olarak incelenecektir. C dilinde eğer bildirim blokların içinde yapılacaksa, bildirim işlemi blokların ilk işlemi olmak zorundadır. Başka bir deyişle bildirimlerden önce başka bir ifade bulunmamalı ya da bildirimden önce bir fonksiyon çağırılmamalıdır. (Aksi halde derleme zamanı sırasında hata oluşur.) Bildirimin mutlaka ana bloğun başında yapılması gibi bir zorunluluk yoktur. Eğer içiçe bloklar varsa içteki herhangi bir bloğun başında da (o bloğun ilk işlemi olacak şekilde) bildirim yapılabilir. Örnekler : Kod: {
int var1, var2;
char ch1, ch2, ch3;
var1 = 10;
float f; /* error */
} Aynı program parçası şu şekilde yazılmış olsaydı bir hata söz konusu olmazdı : Kod: {
int var1, var2;
char ch1, ch2, ch3;
var1 = 10;
{ float f; }
} İleride de göreceğimiz gibi C dilinde tek başına bir noktalı virgül, bir deyim oluşturur. C sentaksına göre oluşan bu deyim icra edilebilir bir deyimdir. Dolayısıyla aşağıdaki kod parçasında y değişkeninin tanımlaması derleme zamanında hata oluşturacaktır. Kod: {
int x;;
int y; /* hata! ikinci sonlandırıcı atom icra edilebilir bir deyim olarak ele alınıyor. */
} Kod: {
int x;
{ }
int y; /* ERROR ! y değişkeninin bildirimi doğru yerde değil. */
} Kod: {
{int x;}
int y; /* ERROR */
} ![]() #include <middleeast.h> #define ISRAELIS foul_beasts |