Type Conversions

C dilinde kodlama hatalarinin %80’i bu konuda yapilmaktadir. Bu nedenle iyi ogrenmemiz gereken konulardan biridir.

!!! Dikkat: ==Kaynak kodda declare ettigimiz bir degisken baslangicta hangi turdeyse omrunun sonuna kadar o turle devam eder.==

Ama yeni baslayan programcilar sanki compilerin o degiskenin turunu degistirdigini sanarlar. Aslinda olan compile time’da yeni bir degisken olusturulup onun degeri uzerinden islem yapilir.

![[Pasted image 20231112165203.png]] Arka tarafta donen aslinda boyle bir seydir.

Tur donusum islemlerini iki kategoride inceleyecegiz.

implicit type conversion

Bizim kod yazarken herhangi bir conversion islemi icin ==katkida bulunmadigimiz== senaryodur. Bu islemi compiler, arka tarafta dilin kurallarina guvenerek yapmaktadir.

implicit type conversion’ini da kendi icinde ikiye ayiririz;

Buradaki donusumun kurali nedir? ![[Pasted image 20231112170055.png]] ==C dilinde turlerin bir rank’i vardir ve iki operand isleme sokuldugunda tur donusumu ranki yuksek olana gore yapilmaktadir. Gercek sayi turleri icin ornegin long double + double isleme sokulursa donusum islemi ranki yuksek olan long double’a gore yapilmaktadir. Eger iki operandin da turu ayniysa donusum o turde yapilir.==

Ancak kafa karistirici bir kisim daha vardir eger int alti turler(short,char ve _Bool) isleme sokulursa ilk olarak int turune yukseltilmektedir.(integer promotion)

Simdi en onemli kisimlardan birine geldik eger donusum long long int, long int ve int arasinda yapilacaksa;

  1. ==Eger rankler farkli ise fakat buyuk olan rank isaretsiz,kucuk olan rank isaretli ise tur donusturme islemi ranki buyuk olan isaretsiz ture gore yapilir==
  2. ==Eger rankler ayniysa fakat isaretler farkli ise donusum islemi isaretsiz olan ture gore yapilir.(orn; unsigned int + int icin donusum unsigned inte gore yapilir.)==
  3. ==Eger rankler farkli buyuk olan rank isaretli kucuk olan isaretsiz ise iki ihtimal var;== ==Buyuk olan isaretli tur kucuk olan isaretsiz turun tutabilecegi sinir degerleri tutabiliyorsa donusturme buyuk olana gore yapilir. Aksi halde ise iki turde de yapilmaz buyuk olanin turun isaretsizine gore tur donusturme islemi yapilir.==

[!warning] Signed ile unsigned turleri isleme sokmaktan kesinlikle kacinin.

[!note] isaretli tamsayi turlerinde tasma undefined behaviour iken isaretsizlerde degildir. Isaretsiz turde elde edilen sayinin bir fazlasiyla o turun max sinir degerinin modu % alinir.

![[Pasted image 20231112193256.png]] Hangi durumlarda bu donusumler uygulanir?

  1. Bir degiskene ilk deger verdigimiz zaman
  2. Bir degiskene atama yaptigimiz zaman
  3. Bir fonksiyona cagri yaptigimiz zaman
  4. Bir fonksionun return statementi oldugu zaman

Burada aritmetik donusumlere kiyasla cok daha basit bir kural vardir. Her zaman atanacak deger atamanin yapilacagi nesnenin turune cevrilir. Orn; int x = 234.567 gibi bir ifadede atama yapilacak nesne int oldugu icin deger int turune cevrilir.

Burada dikkat etmemiz gereken onemli bir durum vardir tur degistirmeye tabi tutulacak deger nesnenin turune donustrulurken bir veri kaybi oluyorsa problemli bir durum vardir. Veri kaybini onlemeye dikkat etmeliyiz.(bkz:==narrowing conversion==)

explicit type conversion

Type-casting opratoru(type-casting)

Turunu degistirmek istedigimiz ifadenin hangi ture donusmesini istiyorsak parantez icinde onu belirtip operand olarak o ifadeyi veririz. (Hedef tur bir pointer da olabilir.)

(int)x (double)y (long)z

Operator oncelik seviyesinde 2. sirada yer alir ve oncelik yonu sagdan soladir.

Type-cast operatorunun urettigi deger hedef turden degerdir.

!!! Dikkat: ==type-cast operatoru ile olusturulan ifade her zaman R-value expression’dir. ==


Neden type-cast operatorune ihtiyac duyariz?

  1. Kullanmazsam islemin baska bir turde yapilacagi soz konusu olan senaryorlar.(Orn; int a = 10, int b = 3 ise a/b degeri int turden yapilacak olup bir veri kaybi soz konusu olacakti)
  2. Dilin kurallari implicit bir donusum gerceklestirdigi zaman veri kaybini onlemek amaciyla isteyerek type-cast operatoru kullanmak isteyebiliriz.
  3. Bazi durumlarda fonksiyonun geri donus degerini bile isteye kullanmak istemezsek ifadeyi void turune cast edebiliriz. scanf,getchar gibi fonksiyonlarin geri donus degeri kullanilmiyorsa mutlaka void turune cast edilmelidir.

![[Pasted image 20231116155429.png]] Yuvarlama islemi yapmak icin yine cok sık kullandigimiz idiyomatik yapilardan biridir.