Diğer bazı yanıtlar üzerinde dokundu ancak olarak Öncelikle, açıkça yeterince dile aklıma, aygıtıdır: does bir tamsayı sağlamak üzere çalışmalarını en kütüphane işlevi alır bağlamlarda double
veya float
argüman. Derleyici otomatik olarak bir dönüşüm ekleyecektir. Örneğin sqrt(0)
, iyi tanımlanmıştır ve tam olarak sqrt((double)0)
aynı şekilde davranacaktır ve aynı şey, burada kullanılan diğer tam sayı tipi ifadeler için de geçerlidir.
printf
farklı. Farklıdır çünkü değişken sayıda argüman alır. İşlev prototipi
extern int printf(const char *fmt, ...);
Bu nedenle yazarken
printf(message, 0);
derleyici, ikinci bağımsız değişkenin ne tür printf
olmasını beklediğine dair herhangi bir bilgiye sahip değildir . Yalnızca geçilmesi gereken argüman ifadesinin türüne sahiptir int
. Bu nedenle, çoğu kitaplık işlevinin aksine, bağımsız değişken listesinin biçim dizesinin beklentilerini karşıladığından emin olmak programcı olarak sizindir.
(Modern derleyiciler olabilir bir biçim dizesi içine bakmak ve bir tür uyuşmazlığı var söyleyecektir, ama onlar daha iyi kod artık ayrılmalıyız, çünkü fark edeceksiniz zaman, ne anlama geldiğini gerçekleştirmek için dönüşümleri takmadan başlamak etmeyeceğiz , yıllar sonra daha az yararlı bir derleyiciyle yeniden oluşturulduğunda.)
Şimdi, sorunun diğer yarısı şuydu: (int) 0 ve (float) 0.0'ın, çoğu modern sistemde, her ikisi de sıfır olan 32 bit olarak temsil edildiği göz önüne alındığında, neden yine de kazara çalışmıyor? C standardı sadece "bunun çalışması gerekli değil, kendi başınasınız" diyor, ancak işe yaramamasının en yaygın iki nedenini açıklayayım; bu muhtemelen neden gerekli olmadığını anlamanıza yardımcı olacaktır .
Bir geçerken Birincisi, tarihi nedenlerden ötürü, float
değişken argüman listesi aracılığıyla bu olur terfi için double
en modern sistemlerde, hangi, 64 bit genişliğinde. Yani printf("%f", 0)
64 bit bekleyen bir aranan uca sadece 32 sıfır bit aktarır.
İkinci, eşit derecede önemli neden, kayan noktalı fonksiyon argümanlarının tamsayı argümanlarından farklı bir yerde geçirilebilmesidir . Örneğin, çoğu CPU'nun tamsayılar ve kayan nokta değerleri için ayrı yazmaç dosyaları vardır, bu nedenle, 0'dan 4'e kadar olan argümanların tamsayılarsa r0'dan r4'e, ancak kayan noktalı iseler f0'dan f4'e kadar olan yazmaçlara gitmesi bir kural olabilir. Yani printf("%f", 0)
bu sıfır için f1 yazmacına bakar, ama orada değildir.
printf
a bekliyordouble
ve siz ona bir veriyorsunuzint
.float
veint
makinenizde aynı boyutta olabilir, ancak0.0f
aslındadouble
bir değişken argüman listesine gönderildiğinde (ve bunuprintf
beklediğinde) a'ya dönüştürülür . Kısacası,printf
kullandığınız belirteçlere ve sağladığınız argümanlara dayanarak pazarlığın amacını yerine getirmiyorsunuz.