नमस्ते, और आज फिर से जब मैं C99 मानक में भाषा C पर प्रयोग कर रहा था, तो मुझे एक ऐसी समस्या का सामना करना पड़ा, जिसे मैं समझ नहीं पा रहा था और मुझे विशेषज्ञ की मदद की आवश्यकता थी।

कोड:

    #include <stdio.h>

    int main(void)
   {
    int Fnum = 256; /* The First number to be printed out */

    printf("The number %d in long long specifier is %lld\n" , Fnum , Fnum);

    return 0;
   }

प्रश्न:

1.) जब मैं इस कोड को चलाने का प्रयास करता हूं तो इस कोड ने मुझे एक चेतावनी संदेश दिया।

2.) लेकिन अजीब बात यह है कि, जब मैं विनिर्देशक %lld को %hd या %ld में बदलने की कोशिश करता हूं, चेतावनी संदेश निष्पादन के दौरान नहीं दिखाया गया था और कंसोल पर मुद्रित मूल्य सही अंक है 256, अगर मैं कोशिश करता हूं तो भी सब कुछ सामान्य लगता है %u , %hu और भी %lu। संक्षेप में चेतावनी संदेश और अंकों की गलत छपाई तभी होती है जब मैं long long विनिर्देशक की भिन्नता का उपयोग करता हूं।

3.) ऐसा क्यों हो रहा है??मैंने सोचा था कि लंबे समय तक मेमोरी का आकार 256 मान रखने के लिए काफी बड़ा है, लेकिन इसका उपयोग उचित मूल्य को प्रिंट करने के लिए क्यों नहीं किया जा सकता है ??

चेतावनी संदेश :(उपरोक्त स्रोत कोड के लिए)

C:\Users\Sam\Documents\Pelles C Projects\Test1\Test.c(7): warning #2234: Argument 3 to 'printf' does not match the format string; expected 'long long int' but found 'int'.

मेरा प्रश्न पढ़ने में समय बिताने के लिए धन्यवाद।भगवान भला करे।

1
caramel1995 6 अप्रैल 2011, 22:53

4 जवाब

सबसे बढ़िया उत्तर

यहां तीन चीजें चल रही हैं।

  1. printf तर्कों की एक चर संख्या लेता है। इसका मतलब है कि संकलक नहीं जानता कि किस प्रकार के तर्क (प्रारूप स्ट्रिंग से परे) होने चाहिए। तो यह उन्हें उपयुक्त प्रकार में परिवर्तित नहीं कर सकता है।
  2. ऐतिहासिक कारणों से, हालांकि, एक चर तर्क सूची में पारित होने पर int से छोटे पूर्णांक प्रकारों को int पर "प्रचारित" किया जाता है।
  3. ऐसा लगता है कि आप विंडोज़ का उपयोग कर रहे हैं। विंडोज़ पर, int और long एक ही आकार के हैं, भले ही पॉइंटर्स 64 बिट चौड़े हों (यह माइक्रोसॉफ्ट के हिस्से पर सी 89 का जानबूझकर उल्लंघन है - उन्होंने वास्तव में मानक को सी 99 में बदलने के लिए मजबूर किया ठीक है")।

इस सब का नतीजा यह है: कंपाइलर को आपके int को long long में बदलने की अनुमति सिर्फ इसलिए नहीं है क्योंकि आपने तर्क सूची में %lld का उपयोग किया है। (आपको चेतावनी देने की अनुमति है कि आप कलाकारों को भूल गए हैं, क्योंकि चेतावनियां मानक व्यवहार से बाहर हैं।) %lld के साथ, इसलिए, आपका प्रोग्राम काम नहीं करता है। लेकिन अगर आप किसी भी अन्य आकार के विनिर्देशक का उपयोग करते हैं, तो printf एक तर्क की तलाश में int के समान आकार का होता है और यह काम करता है।

3
zwol 6 अप्रैल 2011, 23:00

आप Fnum वेरिएबल को प्रिंटफ में पास कर रहे हैं, जिसे int टाइप किया गया है, लेकिन यह long long की अपेक्षा कर रहा है। इसका इस बात से बहुत कम लेना-देना है कि एक लंबे लंबे कर सकते हैं में 256 हो सकता है, बस आपके द्वारा चुना गया वेरिएबल int टाइप किया गया है।

यदि आप केवल 256 प्रिंट करना चाहते हैं, तो आप एक स्थिरांक प्राप्त कर सकते हैं जो unsigned long long टाइप किया गया है:

printf("The number %d in long long specifier is %lld\n" ,256 , 256ULL);

या डाली:

printf("The number %d in long long specifier is %lld\n" , Fnum , (long long int)Fnum);
6
yan 6 अप्रैल 2011, 22:58

एक विविध कार्य के साथ काम करते समय, कॉलर और कैली को चर तर्कों के प्रकारों से सहमत होने के लिए किसी तरह की आवश्यकता होती है। प्रिंटफ के मामले में, यह प्रारूप स्ट्रिंग के माध्यम से किया जाता है। जीसीसी प्रारूप स्ट्रिंग को स्वयं पढ़ने के लिए पर्याप्त चतुर है और यह पता लगाता है कि क्या प्रिंटफ तर्कों की उसी तरह व्याख्या करेगा जैसे वे वास्तव में प्रदान किए गए हैं।

आप कुछ मामलों में थोड़े भिन्न प्रकार के तर्कों से बच सकते हैं। उदाहरण के लिए, यदि आप एक शॉर्ट पास करते हैं तो यह परोक्ष रूप से एक इंट में परिवर्तित हो जाता है। और जब sizeof(int) == sizeof(long int) तब भी कोई भेद नहीं है। लेकिन sizeof(int) != sizeof(long long int) तो पैरामीटर उस मामले में प्रारूप स्ट्रिंग से मेल खाने में विफल रहता है।

1
Neil 6 अप्रैल 2011, 22:58

यह varargs C में काम करने के तरीके के कारण है। एक सामान्य फ़ंक्शन के विपरीत, printf() कोई भी तर्क ले सकता है। यह प्रोग्रामर पर निर्भर करता है कि वह printf() को एक सही प्रारूप स्ट्रिंग प्रदान करके क्या उम्मीद करे।

आंतरिक रूप से, printf() इनपुट तर्कों से मेल खाने वाली कच्ची मेमोरी तक पहुंचने के लिए प्रारूप विनिर्देशक का उपयोग करता है। यदि आप %lld निर्दिष्ट करते हैं, तो यह मेमोरी के 64-बिट हिस्से (विंडोज़ पर) तक पहुंचने का प्रयास करेगा और यह व्याख्या करेगा कि इसे long long int के रूप में क्या मिलता है। हालांकि, आपने केवल 32-बिट तर्क प्रदान किया है, इसलिए परिणाम अपरिभाषित होगा (यह आपके 32-बिट int को स्टैक पर आगे दिखाई देने वाले यादृच्छिक कचरा के साथ जोड़ देगा)।

1
Oliver Charlesworth 6 अप्रैल 2011, 22:59