2011-09-20 13 views
14

मैं C Programming Language, 2nd Edition पढ़कर सी सीखने की कोशिश कर रहा हूं। मैं कुछ प्रोग्रामिंग अनुभव है, लेकिन नहीं सीजब एक printf में% d का उपयोग किया जाता है तो फ्लोट चर के साथ क्या होता है?

साथ मैं अध्याय 1 में वर्तमान में कर रहा हूँ मैं है निम्नलिखित कोड:

A: 0.000000 B: 0.15 
A: 1.100000 B: 1.25 
A: 2.200000 B: 2.35 

:


float f; 
    for (f = 0.0; f <= 3; f += 1.1) 
     printf("A: %3f B: %6.2f\n", f, f + 0.15); 

यह उत्पादन प्रिंट ठीक लग रहा है।

printf("A: %3d B: %6.2f\n", f, f + 0.15); 

नई उत्पादन

A: 0 B: 0.00 
A: -1610612736 B: 0.00 
A: -1610612736 B: -625777476808257557292155887552002761191109083510753486844893290688350183831589633800863219712.00 

यहाँ क्या हो रहा है यह है:


अब मैं printf निम्न प्रकार से परिवर्तित? मैं फ्लोट को int में परिवर्तित करने की अपेक्षा करता हूं क्योंकि मैंने% d का उपयोग किया था, लेकिन ऐसा नहीं हुआ। इसके अलावा, मूल्य बी गलत क्यों हुआ? यहां एफ के साथ क्या हुआ?

+2

आपने इसे एक int में बदलने के लिए नहीं कहा था, आपने कहा था कि यह ** ** एक int था! कचरा अंदर कचरा बाहर। –

उत्तर

15

जब आप कहा जाता है:

printf("A: %3d B: %6.2f\n", f, f + 0.15); 

सी स्वचालित रूप से double को float मूल्यों धर्मान्तरित (यह है एक मानक रूपांतरण तब किया जाता है जब आप फ़ंक्शन को कॉल करते हैं जो परिवर्तनीय तर्क लेता है, जैसे कि int printf(const char *fmt, ...);)। तर्क के लिए, हम मानेंगे कि sizeof(int) 4 और sizeof(double) 8 है (अपवाद हैं, लेकिन वे कुछ और बहुत दूर हैं)।

कॉल ने इसलिए पॉइंटर को स्टैक पर धक्का दिया है, साथ ही f के लिए 8-बाइट डबल और f + 0.15 के लिए 8-बाइट डबल जोड़ा है। जब यह प्रारूप स्ट्रिंग को संसाधित कर रहा है, तो %dprintf() बताता है कि आपने स्वरूप स्ट्रिंग के बाद स्टैक पर 4-बाइट int को धक्का दिया था। चूंकि आपने ऐसा नहीं किया है, आपने अपरिभाषित व्यवहार का आह्वान किया है; जो कुछ भी होता है वह सी मानक के अनुसार ठीक है।

हालांकि, सबसे अधिक संभावना कार्यान्वयन 4 बाइट्स को स्पष्ट रूप से पढ़ता है और उन्हें प्रिंट करता है जैसे कि वे int थे (यह आपको सच कहने पर भरोसा करता है)। फिर यह %6.2f प्रारूप में आता है; यह double के रूप में स्टैक से 8-बाइट्स पढ़ेगा। एक बाहरी मौका है कि इससे गलत तरीके से पहुंच के लिए मेमोरी गलती हो जाएगी (इसे एक आवश्यकता के साथ एक 64-बिट मशीन की आवश्यकता होगी जो double को 8-बाइट सीमा, जैसे एसपीएआरसी पर गठबंधन किया जाए), या यह 4 बाइट्स पढ़ेगा f और f + 0.15 से 4 बाइट्स, कुछ उदाहरण के लिए अप्रत्याशित double मान बनाने के लिए उन्हें एक साथ रखकर - जैसा कि आपका उदाहरण दिखाता है।

+0

बहुत अच्छा जवाब, तो आप 'printf ("ए:% d% d बी:% 6.2", ...' और गलत हो सकता है एक vals लेकिन बी प्रभावित नहीं होगा –

+1

काफी हद तक अनुमानित धारणाओं के तहत, हां व्यवहार सख्ती से अपरिभाषित है, लेकिन व्यवहार में, हाँ। –

8

प्रिंटफ उस स्मृति का इलाज करेगा जैसा आप बताते हैं। कोई रूपांतरण नहीं चल रहा है। यह उस स्मृति का इलाज कर रहा है जो एक इंट के रूप में फ्लोट का प्रतिनिधित्व करता है। क्योंकि दोनों अलग-अलग संग्रहित होते हैं, इसलिए आपको अनिवार्य रूप से यादृच्छिक संख्या मिलती है।

आप उत्पादन के लिए एक पूर्णांक के रूप में अपने नाव चाहते हैं, आप यह पहली बार डाली चाहिए:

printf("A: %3d B: %6.2f\n", (int)f, f + 0.15); 
+1

ठीक है, यह समझ में आता है। तो क्या एफ का मूल्य बदल गया क्योंकि मैंने इसे int के रूप में नहीं डाला था? यदि नहीं, तो printf का दूसरा भाग% 6.2f का उपयोग कर रहा है, तो क्या कम से कम सही मूल्य होना चाहिए? – Gollum

संबंधित मुद्दे