Veri Tipleri

Temel Veri Tipleri

C'de veriler farklı uzunluktaki kısımlarda tutulurlar. Bir verinin ne kadar bellek kaplayacağı tipiyle alakalıdır. C89 standartları 5 farklı tip tanımlar. Bunlar char (karakter), int (tam sayı), float (küsuratlı sayı), double (daha hassas küsuratlı sayı) ve void (değersiz)'dir. C99 bunlara _Bool veri tipini de eklemiştir.

char tipindeki bir veri 8 bit yer kaplar ve genellikle tek bir karakter için kullanılır (Her bir karakterin 8 bitlik bir ASCII kodu karşılığı vardır.). Fakat 8 bite sığabilecek sayıları da ifade etmek için kullanılabilir. Misalen; "A" karakteri bellekte şu şekilde depolanır:

01000001

char tipinde depolanan verinin sayısal değerinde ikilik sayı sistemi mantığı kullanılır. Fakat ilk basamağın faktörü \(2^7\) değil \(-2^7\)'dir.

Pozitif sayılar için ilk basamak sıfır olduğunda direkt ikili sayı sistemi mantığı kullanılabilir. Misalen yukarıdaki sayının değeri 65'tir. Negatif sayıların nasıl depolandığını bulmak için de pratik bir yol vardır. Örneğin -65 sayısını yazmak isteyelim:

1) Önce 65 sayısı ikili sistemde yazılır: 01000001
2) Sonra sayıdaki birler sıfıra, sıfırlar bire çevrilir: 10111110
3) Sayıya bir eklenir: 10111111

Şimdi yeni bulduğumuz sayının yaptığımız ilk tanımla değerini bulup sonucumuzun doğruluğunu teyit edelim:

\(\begin{align*}1\times(-2)^7+0\times2^6+1\times2^5+1\times2^4+ 1\times2^3+ 1\times2^2+ 1\times2^1+ 1\times2^0 \end{align*}\)

\(=-128+32+16+8+4+2+1=-65\)

int kullanılan işletim sistemine göre 16 veya 32 bit yer kaplar. Sayıların yazımı yine char ile aynı şekildedir. En baştaki basamak hesaba yine eksili olarak katılır. Negatif sayı bulmada char için önerilen pratik yöntem burada da işe yarar.

float tipindeki sayılar 32 bit yer kaplar ve bu tip küsuratlı sayılar için kullanılır. Bu sayıların depolanış şekli biraz farklı bir mantık içerdiğinden girilen veriler çok küçük mertebede de olsa hatalı depolanabilir. float tipindeki sayılar \(a\times 2^b\) biçiminde ve aşağıdaki şekilde depolanır.

En baştaki 1 bit işareti belirtmek için kullanılır. "0" pozitif, "1" negatifdir.
Sonraki 8 bitin oluşturduğu tam sayı kullanılarak elde edilen değer 2'nin üzerine üs olarak gelir. Bu bahsi geçen değer, 8 bitin oluşturduğu sayının 127 eksiğidir.
Daha sonraki 23 bit ise üslü sayının başına gelecek çarpanı belirler. Bu kısımdaki basamaklar soldan sağa doğru sırayla ikide birler, dörtte birler, sekizde birler, ... basamaklarını ifade eder. Elde edilen sayı 1 ile toplanarak üslü sayıya çarpan olur.

Hemen bir örnek ile deneyelim:

00111111001100000000000000000000

Bu sayıyı daha anlaşılır bir şekilde kısımlara ayıralım:

0 01111110 01100000000000000000000

İlk basamağın 0 olması sayının pozitif olduğu manasına gelir.
Sonraki sekiz bit "01111110" sayısını oluşturur. Bu sayı onluk sistemde 126'ya karşılık gelir.
Daha sonraki 23 bit "01100000000000000000000" sayısını oluşturur ve bunun da onluk sistemdeki karşılığı: \(2^{-2}+2^{-3}=0,25+0,125=0,375\)'tir.

Bu durumda depolanan sayı şudur: \((1+0.375)\times2^{126-127}=0,6875\)

İstisnai bir durum olarak üs olacak değeri belirleyen 8 bitin "0" değerini alması durumunda çarpanı oluşturacak 23 bitin meydana getirdiği sayı 1 ile toplanmaz. Bunun dışında 8 bitin oluşturduğu sayının 255 olması durumu tanımlı bir küsuratlı sayı meydana getirmez.

double tipi float ile benzerdir fakat daha hassastır. Bu veri tipi 64 bitlik yer tutar ve bu 64 bitin 1 biti işaret 11 biti çarpan ve 52 biti de üs için kullanılır.

void tipi ise genellikle fonksiyonlarda kullanılan ve sonuçta bir değer oluşması gerekmediğini veya fonksiyona bir değer girilmesi gerekmediğini belirtmeye yarayan değişken türüdür.

C89 standartlarında tanımlanan beş veri tipi bunlardır.

C99 ile birlikte gelen _Bool tipi doğru veya yanlış şeklinde depolanmak istenen veriler için kullanılır ve bu tipte tanımlanan bir değişken sadece 1 veya 0 değerine eşit olur. _Bool tipinin bellekte ne kadar yer kaplayacağı net bir şekilde tanımlanmamıştır fakat 1 veya 0 değerini tutabilecek en küçük tip büyüklüğünde olmak zorundadır. Bu nedenle genellikle 8 bit yer kaplamaktadır.


Modifiye Elemanları

Temel veri tiplerini modifiye etmeye yarayan dört eleman vardır: signedunsignedshort ve long. Şimdi bu elemanları tek tek inceleyelim:

signed: char ve int veri tiplerini modifiye etmede kullanılır. Bu modifiye elemanı kullanılırsa modifiye edilen veri tipinin ilk biti işaret bilgisi için kullanılır. char ve int tiplerinin standart hallerinde de ilk bit işaret bilgisi için kullanıldığından bu modifiye elemanı büyük oranda gereksizdir. Bu modifiye elemanını kullanmanın gerekebileceği tek durum char tipinin standart olarak işaretsiz tanımlandığı hallerdir.

unsigned: char ve int veri tiplerini modifiye etmede kullanılır. Bu modifiye elemanı kullanılırsa modifiye edilen veri tipinin ilk biti işaret bilgisi için kullanılmaz. Bu durumda tam sayı bellekte tutulurken ilk bitinin basamak faktörü de eksisiz olarak hesaba katılır:

Örnek verecek olursak;

Diyelim ki char tipindeki bir veri için bellekte depolanan değer 11001110 olsun. Bu değerin karşılığı char'ın signed olması ve unsigned olması durumunda ne olur?

Signed olması durumunda:

\(1\times2^{-7}+1\times2^{6}+1\times2^{3}+1\times2^{2}+1\times2^{1}=-50\)

Unsigned olması durumunda:

\(1\times2^{7}+1\times2^{6}+1\times2^{3}+1\times2^{2}+1\times2^{1}=206\)

unsigned modifiye elemanının kullanılması bellekte tutulabilecek pozitif sayı aralığını iki katına çıkarır fakat negatif sayı kullanılmasına müsaade etmez.

long: int ve double tiplerini modifiye etmek için kullanılır. int tipi bu modifiye elemanı ile modifiye edildiğinde işletim sistemine ve derleyiciye bağlı olmaksızın 32 bit yer kaplar. double bu modifiye elemanıyla modifiye edildiğinde ise 80 bit yer kaplar ve veriler daha hassas bir şekilde depolanır. long modifiye elemanı signed ve unsigned modifiye elamanlarından sonra da kullanılabilir. C99 standartları int tipi için long long şeklinde modifiyeye de imkan vermiştir. Bu şekilde modifiye edilen veri 64 bit yer kaplar.

short: int veri tipini modifiye etmek için kullanılır. Bu modifiye elemanı kullanıldığında int tipi işletim sisteminden ve derleyiciden bağımsız olarak 16 bit yer kaplar.

C99 standartları _Complex ve _Imaginary olmak üzere iki farklı kelime tanımlamıştır. Bu kelimeler yardımıyla aşağıdaki veri tipleri oluşturulabilmektedir.

float _Complex
float _Imaginary
double _Complex
double _Imaginary
long double _Complex
long double _Imaginary

Bu kelimeler tüm derleyicilerce desteklenmek zorunda olmamakla birlikte karmaşık sayıları depolamak için kullanılırlar. Karmaşık sayıları oluşturabilmek için "complex.h" kütüphanesinin kullanılması gerekir. Bunu da ilerleyen bölümlerde göreceğiz. Şimdilik bu kelimelerin ne işe yaradıklarına kısaca değinelim:

_Complex: Bu şekilde oluşturulan bir değişken başındaki tip şeklinde bir reel kısım ve yine başındaki tip şeklinde bir imajiner kısımdan oluşur.

_Imaginary: Bu şekilde oluşturulan bir değişken başındaki tip şeklinde bir imajiner sayıdan oluşur.


Verilerin Kapladığı Bellek Alanları ve Tutabilecekleri Değer Aralıkları


char
8 bit - [-127, 127]
signed char
8 bit - [-127, 127]
unsigned char
8 bit - [0, 255]
int
16/32 bit - [-32.767, 32.767]/[–2.147.483.647, 2.147.483.647]
signed int
16/32 bit - [-32.767, 32.767]/[–2.147.483.647, 2.147.483.647]
unsigned int
16/32 bit - [0, 65.535]/[0, 4.294.967.295]
short int
16 bit - [-32.767, 32.767]
signed short int
16 bit - [-32.767, 32.767]
unsigned short int
16 bit - [0, 65.535]
long int
32 bit - [–2.147.483.647, 2.147.483.647]
signed long int
32 bit - [–2.147.483.647, 2.147.483.647]
unsigned long int
32 bit - [0, 65.535]/[0, 4.294.967.295]
long long int (C99 ile eklenmiştir.)
64 bit - [–9.223.372.036.854.775.808, 9.223.372.036.854.775.807]
signed long long int (C99 ile eklenmiştir.)
64 bit - [–9.223.372.036.854.775.808, 9.223.372.036.854.775.807]
unsigned long long int (C99 ile eklenmiştir.)
64 bit - [0,18.446.744.073.709.551.615]
float
32 bit - +/- [1.2E-38, 3.4E+38] (6-7 basamak hassasiyet)
double
64 bit - 0 ve +/- [2.2E–308, 1.8E+308] (15-16 basamak hassasiyet)
long double (C99 ile eklenmiştir.)
80 bit - 0 ve +/- [3.4E-4932, 1.2E4932] (19-20 basamak hassasiyet)


Bunun dışında bilinmesi gereken bir başka şey de modifiye elemanları tek başlarına kullanıldığında sanki sonlarında int varmış gibi algılanacağıdır.




Giriş <<<<< Temel C >>>>> Değişkenler