2016-11-26 7 views
15

मैंने अपनी परियोजनाओं में निश्चित रूप से निश्चित पूर्णांक प्रकारों पर स्विच किया क्योंकि मुख्य रूप से वे मुझे पूर्णांक आकारों के बारे में सोचने में अधिक स्पष्ट रूप से सोचने में मदद करते हैं। #include <inttypes.h> के माध्यम से उन्हें भी शामिल है भी मुद्रण मैक्रो PRIu32, PRIu64, ...मुझे UINT32_C(), INT32_C(), ... में मैक्रोज़ का उपयोग कब करना चाहिए?

एक निश्चित लंबाई चर रहा UINT32_C() और INT32_C() तरह मैक्रो का उपयोग कर सकते हैं करने के लिए एक स्थिर मान असाइन करने के लिए जैसे अन्य मैक्रो का एक समूह भी शामिल है। जब भी मैंने निरंतर मूल्य आवंटित किया तो मैंने उनका उपयोग करना शुरू कर दिया।

यह इस के समान कोड की ओर जाता है:

uint64_t i; 
for (i = UINT64_C(0); i < UINT64_C(10); i++) { ... } 

अब मैं कई उदाहरण है जो उस के बारे में परवाह नहीं देखा। एक stdbool.h फ़ाइल शामिल है:

#define bool _Bool 
#define false 0 
#define true 1 

bool मेरी मशीन पर 1 बाइट के आकार की है, तो यह एक int तरह नहीं दिखता है। लेकिन 0 और 1 पूर्णांक होना चाहिए जो स्वचालित रूप से कंपाइलर द्वारा सही प्रकार में बदल दिया जाना चाहिए। तो मुझे लगता है कि प्रयोग करेंगे मेरी उदाहरण में कोड बहुत आसान होता पढ़ने के लिए:

uint64_t i; 
for (i = 0; i < 10; i++) { ... } 

तो जब मैं UINT32_C() की तरह निश्चित लंबाई लगातार मैक्रो का उपयोग करना चाहिए जब मैं संकलक करने के लिए है कि काम छोड़ देना चाहिए (मैं कर रहा हूँ जीसीसी का उपयोग कर)? अगर मैं मिसरा सी में कोड लिखूंगा तो क्या होगा?

+3

व्यक्तिगत रूप से मैं निश्चित चौड़ाई प्रकारों का उपयोग करने से दूर शर्मिंदा हूं: सभी कंपाइलर्स उनका समर्थन नहीं करते हैं और इन प्रकारों के साथ पदोन्नति नियम व्यावहारिक रूप से अस्तित्व में नहीं हैं - मेरी विनम्र राय में सी मानक में एक बड़ी निगरानी है। हालांकि सवाल के लिए उपरोक्त। – Bathsheba

+1

दिलचस्प सवाल, – cat

+1

उत्तरों को देखने के लिए इंतजार नहीं कर सकता है यदि आपको 'बिट '32 बिट्स से कम है तो आपको उनकी आवश्यकता हो सकती है। – nwellnhof

उत्तर

4

अंगूठे के नियम के रूप में, आपको शाब्दिक मामलों के प्रकार के दौरान उनका उपयोग करना चाहिए। विचार करने के लिए दो चीजें हैं: आकार और हस्ताक्षर।

एक int प्रकार 32767 अप करने के लिए सी मानक मूल्यों द्वारा गारंटीकृत है:

आकार के बारे में

। चूंकि आप int से छोटे प्रकार के साथ एक पूर्णांक शाब्दिक नहीं प्राप्त कर सकते हैं, इसलिए 32767 से छोटे सभी मानों को मैक्रोज़ का उपयोग करने की आवश्यकता नहीं है। यदि आपको बड़े मूल्यों की आवश्यकता है, तो शाब्दिक प्रकार का मामला महत्वपूर्ण है और उन मैक्रोज़ का उपयोग करना एक अच्छा विचार है।

signedness के बारे में:

कोई प्रत्यय के साथ

पूर्णांक शाब्दिक एक हस्ताक्षरित प्रकार के आम तौर पर कर रहे हैं। यह संभावित रूप से खतरनाक है, क्योंकि यह अंतर्निहित प्रकार के प्रचार के दौरान सभी प्रकार की सूक्ष्म बग का कारण बन सकता है। उदाहरण के लिए (my_uint8_t + 1) << 31 32 बिट सिस्टम पर एक अपरिभाषित व्यवहार बग का कारण बनता है, जबकि (my_uint8_t + 1u) << 31 नहीं होगा।

यही कारण है कि एमआईएसआरए के पास एक नियम है कि सभी पूर्णांक अक्षरों में u/U प्रत्यय होना चाहिए यदि इरादा बिना हस्ताक्षर किए गए प्रकारों का उपयोग करना है। तो ऊपर दिए गए मेरे उदाहरण में आप my_uint8_t + UINT32_C(1) का उपयोग कर सकते हैं लेकिन आप 1u का भी उपयोग कर सकते हैं, जो शायद सबसे अधिक पठनीय है। मिसरा के लिए या तो ठीक होना चाहिए।


क्यों stdbool.h सच/गलत को 1/0 होने के लिए परिभाषित करता है, ऐसा इसलिए है क्योंकि मानक स्पष्ट रूप से ऐसा कहता है। सी में बूलियन की स्थिति अभी भी int प्रकार का उपयोग करती है, और पिछली संगतता कारणों के लिए bool प्रकार C++ में टाइप नहीं है।

हालांकि यह बूलियन स्थितियों के इलाज के लिए अच्छी शैली माना जाता है जैसे सी के पास एक असली बूलियन प्रकार था। मिसरा-सी: 2012 में इस अवधारणा के संबंध में नियमों का एक पूरा सेट है, जिसे कहा जाता है जिसे अनिवार्य रूप से बूलियन प्रकार कहा जाता है। यह स्थैतिक विश्लेषण के दौरान बेहतर प्रकार की सुरक्षा प्रदान कर सकता है और विभिन्न बग को भी रोक सकता है।

+0

इंटीजर आकार या तो कोई फर्क नहीं पड़ता। इंटीजर लिटलल सबसे छोटे प्रकार के होंगे जो शाब्दिक मूल्य, या ('हस्ताक्षरित') 'int', जो भी अधिक हो, पकड़ सकते हैं। – alecov

2

यह छोटे पूर्णांक अक्षरों का उपयोग करने के लिए है जहां संदर्भ का परिणाम संकलक को सही आकार में नहीं डालेगा।

मैंने एक एम्बेडेड प्लेटफ़ॉर्म पर काम किया है जहां int 16 बिट्स और long 32 बिट्स है। यदि आप 16-बिट या 32-बिट int प्रकारों के साथ प्लेटफार्मों पर काम करने के लिए पोर्टेबल कोड लिखने की कोशिश कर रहे थे, और एक वैरिएड फ़ंक्शन में 32-बिट "हस्ताक्षरित पूर्णांक अक्षर" पास करना चाहते थे, तो आपको कास्ट की आवश्यकता होगी:

#define BAUDRATE UINT32_C(38400) 
printf("Set baudrate to %" PRIu32 "\n", BAUDRATE); 

16-बिट प्लेटफार्म पर डाली 38400UL और 32-बिट मंच सिर्फ 38400U पर बनाता है। वे PRIu32 मैक्रो "lu" या "u" से मेल खाएंगे।

मुझे लगता है कि सबसे compilers (uint32_t) XUINT32_C(X) जब X एक पूर्णांक शाब्दिक है के लिए के रूप में के लिए समान कोड उत्पन्न होगा, लेकिन है कि जल्दी compilers के साथ मामला नहीं हो सकता।

+0

मैंने लुंडिन्स का जवाब स्वीकार किया, लेकिन विविधता कार्यों का उल्लेख करने के लिए +1। – TimFinnegan

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