2010-02-16 21 views
9

Bu program üzerinde çalışıyordum ve bir float için% f ve% d kullanmanın bana tamamen farklı bir şey verdiğini fark ettim. Bunun neden olduğunu bilen var mı? C printf% d ve% f kullanarak

int main() 
{ 
float a = 1F; 
double b = 1; 

printf("float =%d\ndouble= %f", a, b); 
} 

Bu

çıkış Verilerin iç temsiller ile ilgisi var

float = -1610612736 
double = 190359837192766135921612671364749893774625551025007120912096639276776057269784974988808792093423962875123204096.0000 
+0

sayesinde. şimdi anladım. – user69514

cevap

4

Değişken parametrelerin çalışma şekli nedeniyle, C, %d ve %f'dan başka bir şekilde geçirdiğiniz değer türü hakkında hiçbir fikri yoktur. Bir değişken parametresini ilettiğinizde, temel olarak (void*)&myvalue yapıyorsunuz, çünkü ne derleyici ne de çalışma zamanında işlev, biçimlendirme dizesinde verilenler dışında değişkenin türünü belirleyemez. Bu nedenle, örtük bir dönüşüm mevcut olsa da, derleyici gerekli olduğunu bilmez.

Çoğu sistemde float 4 bayt iken, çift 8 bayttır. Yani iki tip olduğu gibi ikili uyumlu değildir. Ve bir dizeyi bir çift veya başka bir uyumsuz tür olarak yorumlamaya çalışmak gibidir.

+2

Doğru, ama gerçekten 'float' ve 'double' arasındaki uyumluluk ile ilgili değildir. Aslında, float türünün değişkenli argümanları her zaman geçişten önce 'double' olarak adlandırılır, yani float'ın buradaki herhangi bir şeye dahil olmadığı anlamına gelir. Printf'e iletilen her iki değer de double tipine sahiptir. İlkinde bir 'int' ('% d' belirteci nedeniyle) olarak yorumlanır. 'Int' ve 'double' arasındaki uyumsuzluk, gözlemlenmemiş davranışa neden olan şeydir. – AnT

3

olduğunu. Bir float, tamamen farklı bir iç (ikili) temsile sahip bir int olduğu gibi yazdırmaya çalışıyorsunuz.

çift kasa benzerdir. Float değişkeninden sonra muhtemelen bir çöpünüz var demektir. Bu çöp çifte değerin bir parçası olarak yorumlanır.

4

%d ondalık için duruyor ve int türünde bir argüman (veya daha sonra tanıtılan bazı küçük imzalı tamsayı türü) bekler. Kayan nokta türleri float ve double her ikisi de aynı şekilde (double için tanıtıldı) geçti ve her ikisi de %f kullanın. C99'da, double'un büyük boyutunu belirtmek için %lf'u da kullanabilirsiniz, ancak bu yalnızca kozmetiktir (scanf ile hiçbir promosyonun gerçekleşmediğini ve bunun aslında bir fark yarattığını unutmayın).

+0

Eh, bu doğru http://codepad.org/labE8lgy ama nasıl çalıştığını gerçekten merak ediyorum .. – Earlz

0

% d bir tam sayı basar, bu nedenle printf dosyanız değişkeninizi int olarak yorumluyor.

gcc 3.4.6 ile, kodunuzla birlikte her iki değer için de 0'ları alıyorum (bir derleyicinin hata vermesine neden olan bir başlangıçtan sonra F'yi aldıktan sonra). Bunun bir int olarak yorumlanmakta olan bir değişkenin parçası ile ilgili olduğundan şüpheleniyorum ve derleyici kafam karıştı ... (muhtemelen daha iyi bir açıklama var, ama bunu düşünemiyorum).

Her iki değişken için de her iki değişken baskı için de 1.000000'ü kullanın.

Bu sayfa altına yakın dönüşüm karakterlerin bir listesini bulabilirsiniz: Tüm yorumlar için

http://www.exforsys.com/tutorials/c-language/managing-input-and-output-operations-in-c.html

+0

'F' ile ilişkili derleyici hatası, bir tam sayıya eklenemediği için (ör.,' 1.0F' iyi). – RastaJedi