2017-07-19 14 views
5

में निम्नलिखित कोड काम करता है:डेटा प्रकार भ्रम सी

int main(void) 
{ 
    float f = get_float(); 
    int i = round(f*100); 
    printf("%i\n", i); 
} 

फिर भी, त्रुटि उत्पन्न करता है, तो इस तरह से कोडिंग:

printf("%i\n", round(1.21*100)); 

आउटपुट का कहना है round(1.21*100)float है। तो, फिर

int i = round(f*100); 

ठीक है?

+3

जब एक 'float' मूल्य' int' मूल्यों को सौंपा गया है, एक आंतरिक रूपांतरण जगह लेता है। 'राउंड() 'एक डबल मान देता है, इसलिए यदि कोई रूपांतरण नहीं किया जाता है तो यह मान दोहरा रहता है। इस निर्दिष्ट मामले में 'printf ("% i \ n", राउंड (1.21 * 100));' कोई रूपांतरण नहीं किया जाता है, इसलिए इसे फ्लोट वैल्यू प्रिंट करने के लिए '% f' निर्दिष्ट करने की आवश्यकता होती है। – Sma

उत्तर

15

जब आप

int i = round(f*100); 

आपdouble समारोह round का परिणाम परिवर्तित । परिवर्तित परिणाम int परिवर्तनीय i में संग्रहीत किया जाता है, जिसका प्रारूप "%i" प्रारूप के साथ उपयोग किया जा सकता है क्योंकि यह int तर्क की अपेक्षा करता है।

जब आप सीधे एक प्रारूप करने के लिए एक तर्क है कि एक int आप बेमेल प्रारूप और तर्क प्रकार की उम्मीद के रूप में round की double परिणाम गुजरती हैं। इससे अपरिभाषित व्यवहार तक पहुंच जाता है।

कोई रूपांतरण printf करने के लिए कॉल में किया जाता है, और कोई रूपांतरण के बाद से printf समारोह के अंदर कोड तर्क के वास्तविक प्रकार पता नहीं है बनाया जा सकता है। यह सब जानता है प्रारूप "%i" है। परिवर्तनीय-तर्क कार्यों के लिए सभी संभावित प्रकार-जानकारी खो जाती है।

+0

अच्छी तरह से, "कोई रूपांतरण नहीं किया गया है", फिर भी डिफ़ॉल्ट तर्क प्रचार किया जाता है। –

+0

@AnttiHaapala ठीक है क्योंकि फ़ंक्शन एक 'डबल' मान देता है, और डिफ़ॉल्ट तर्क पदोन्नति' डबल 'होगी, इस विशिष्ट मामले में कोई रूपांतरण नहीं किया जाता है। –

5

यह स्वचालित प्रकार कास्टिंग के व्यवहार की वजह से है। Printf में, स्वचालित टाइपकास्टिंग काम नहीं करता है। जब आप% i कहते हैं, तो यह केवल पूर्णांक की अपेक्षा करता है, यह डबल से पूर्णांक में परिवर्तित नहीं हो सकता है और फिर प्रिंट कर सकता है।

असाइनमेंट ऑपरेशन में, डबल को पहले पूर्णांक में परिवर्तित किया जाता है और फिर इसे = ऑपरेटर के बाएं ऑपरेंड को असाइन किया जाता है। आशा है कि ये आपकी मदद करेगा।

4

इस दोहराव का एक सा है, लेकिन शायद एक बेहतर समझ के लिए मदद करता है:

  1. round() निम्नलिखित प्रोटोटाइप है:

    double round(double x); 
    

    तो यह रिटर्न double

  2. वहाँ double से एक अंतर्निहित रूपांतरण सी में int, तो

    int i = round(f*100); 
    

    लेखन int को round() का परिणाम परिवर्तित कर देगी।

  3. यदि आपके पास कोई ऐसा कार्य है जो int की अपेक्षा करता है, उदा।

    void printMyNumber(int number) 
    { 
        printf("%i\n", number); 
    } 
    

    आप इस तरह यह कॉल कर सकते हैं:

    printMyNumber(round(f*100)); 
    

    और क्योंकि संकलक दोनों प्रकार के (round() से वापसी प्रकार और printMyNumber() की उम्मीद तर्क प्रकार) देखता है अंतर्निहित रूपांतरण के रूप में उम्मीद काम करता है।

  4. कारण इस printf() साथ काम नहीं करता है कि printf() के प्रोटोटाइप इस तरह दिखता है:

    printf(const char *format, ...); 
    

    हां, तो पहले तर्क के अलावा, तर्क के प्रकार अज्ञात हैं। इसलिए, जो कुछ भी आप पास करते हैं उसे बिना किसी रूपांतरण के पास किया जाता है (default argument promotions को छोड़कर)। बेशक, आप के बजाय एक स्पष्ट रूपांतरण प्राप्त करने के लिए एक डाली इस्तेमाल कर सकते हैं:

    printf("%i\n", (int) round(f*100)); // <- this is fine 
    
संबंधित मुद्दे