2009-12-02 8 views
5

मेरे पास एक हस्ताक्षरित पूर्णांक है लेकिन जब मैं इसे% d का उपयोग करके प्रिंट करता हूं तो कभी-कभी नकारात्मक मान होता है?सी बिना हस्ताक्षर किए गए int को ऋणात्मक मूल्य प्रदान करना?

+1

देखें कि क्या आपके कंपाइलर के पास इस तरह की त्रुटि के बारे में चेतावनी देने का विकल्प है। यह है - जीसीसी के साथ वर्फैट। –

+0

संभावित डुप्लिकेट [मैं एक हस्ताक्षरित पूर्णांक के अधिकतम मूल्य को कैसे मुद्रित कर सकता हूं?] (Http://stackoverflow.com/questions/12812812/how-can-i-print-maximum-value-of-an-unsigned-integer) –

उत्तर

10

यह काम करना चाहिए:

unsigned int a; 
printf("%u\n", a); 

स्पष्टीकरण: सबसे आर्किटेक्चर पर, पर हस्ताक्षर किए पूर्णांक two's complement में प्रतिनिधित्व कर रहे हैं। इस प्रणाली में, सकारात्मक संख्या 2**(N-1) (जहां N = sizeof(int)) से कम है, इस पर ध्यान दिए बिना कि आप int या unsigned int का उपयोग कर रहे हैं या नहीं। हालांकि, अगर आपके हस्ताक्षरित int में संख्या 2**(N-1) से बड़ी है, तो यह दो के पूरक के तहत एक नकारात्मक हस्ताक्षरित संख्या का प्रतिनिधित्व करती है - जो printf ने आपको "%d" पास करने पर दिया था।

26

प्रिंटिंग %d इसके परिभाषित प्रकार के बावजूद, एक हस्ताक्षरित दशमलव संख्या के रूप में पूर्णांक को पढ़ेगा।

हस्ताक्षरित संख्या मुद्रित करने के लिए, %u का उपयोग करें।

यह परिवर्तनीय तर्कों को संभालने के लिए सी के तरीके के कारण होता है। कंपाइलर केवल स्टैक से मूल्य खींचता है (void* के रूप में टाइप किया गया है और कॉल स्टैक को इंगित करता है) और printf को यह पता लगाना होगा कि उस प्रारूप स्ट्रिंग से डेटा में क्या है।

यही कारण है कि आप प्रारूप स्ट्रिंग की आपूर्ति करने की जरूरत है - सी RTTI का कोई रास्ता नहीं है या एक 'आधार वर्ग' (जावा में Object, उदाहरण के लिए) से एक सामान्य या पूर्वनिर्धारित toString प्राप्त करने के लिए है।

+4

नाइटपिक: सी मूल्य से कॉल किया जाता है, इसलिए संकलक तर्क मान खींचता है, पॉइंटर्स नहीं। आप पॉइंटर्स को मानों (printf ("% u", और myvariable) को पास नहीं करते हैं;), आप सीधे मान पास करते हैं (printf ("% u", myvariable);)। – unwind

+1

यह वास्तव में ढेर के लिए 'printf' एक सूचक देता है, हालांकि। – LiraNuna

+0

@LiraNuna - varargs फ़ंक्शन का कार्यान्वयन निर्दिष्ट नहीं है, यही कारण है कि न तो '# परिभाषित va_copy (dest, src) dest = src' या' # परिभाषित va_copy (dest, src) memcpy (dest, src, sizeof (va_list)) 'सिस्टम पर 'va_copy' मैक्रो के लिए एक पोर्टेबल प्रतिस्थापन है जहां यह प्रदान नहीं किया गया है। उनमें से एक काम कर सकता है, लेकिन कौन जानता है? –

4

% डी का अर्थ है printf मूल्य को int (जिसे हस्ताक्षरित किया गया है) के रूप में समझेंगे। यदि आप एक हस्ताक्षरित int है तो% u का उपयोग करें।

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