2013-08-14 3 views
10

स्पष्ट रूप से एक संभावना है कि सादा char या तो डिफ़ॉल्ट रूप से हस्ताक्षरित या हस्ताक्षरित किया जा सकता है। स्ट्राउस्ट्रप लिखते हैं:कैसे जांचें कि सादे वर्ण हस्ताक्षरित हैं या हस्ताक्षरित हैं या नहीं?

यह कार्यान्वयन-परिभाषित किया गया है कि क्या एक सादे चार को हस्ताक्षरित या हस्ताक्षरित माना जाता है। इससे कुछ खराब आश्चर्य और कार्यान्वयन निर्भरताओं के लिए संभावना खुलती है।

मैं कैसे जांचूं कि मेरे वर्ण हस्ताक्षरित हैं या हस्ताक्षरित हैं या नहीं? मैं उन्हें बाद में int में परिवर्तित करना चाहता हूं, और मैं नहीं चाहता कि वे नकारात्मक हों। क्या मुझे हमेशा unsigned char स्पष्ट रूप से उपयोग करना चाहिए?

+0

@ मिच व्हाट: हाँ। जिन उदाहरणों का मैंने सामना किया है: क्रे टी 0 9 0, क्रे एसवी 1, क्रे टी 3 ई, एसजीआई एमआईपीएस आईआरईएक्स, आईबीएम पावरपीसी एईक्स। और ईबीसीडीआईसी का उपयोग करने वाली किसी भी प्रणाली को काफी 'char' को हस्ताक्षर नहीं करना है। –

+0

@KeithThompson: आप के जवाब के रूप अपनी सूची में जोड़ना चाहिए [इस सवाल] (http://stackoverflow.com/questions/3728045/any-compiler-which-takes-char-as-unsigned) – jxh

+0

आप संकलक के दस्तावेज़ पढ़ें । –

उत्तर

13

कुछ विकल्प:

const bool char_is_signed = (char)-1 < 0; 

#include <climits> 
const bool char_is_signed = CHAR_MIN < 0; 

और हाँ, कुछ सिस्टम सादा char एक अहस्ताक्षरित प्रकार कर सकता हूँ। जिन उदाहरणों का मैंने सामना किया है: क्रे टी 0 9 0, क्रे एसवी 1, क्रे टी 3 ई, एसजीआई एमआईपीएस आईआरईएक्स, आईबीएम पावरपीसी एईक्स। और ईबीसीडीआईसी का उपयोग करने वाली किसी भी प्रणाली को सादा char को हस्ताक्षर करना है ताकि सभी मूल पात्रों के पास गैर-ऋणात्मक मान हों। , के रूप में Benjamin Lindley's answer ने सुझाव दिया, शायद और अधिक स्पष्ट रूप से आशय व्यक्त करता है (और कुछ compilers ऐसे जीसीसी के -fsigned-char और -funsigned-char रूप char की signedness, नियंत्रित करने के लिए एक विकल्प है।)

लेकिन std::numeric_limits<char>::is_signed

(दूसरी ओर, तरीकों मैं सुझाव भी सी के लिए लागू किया जा सकता है)

-1

आप पूर्वप्रक्रमक आदेश का उपयोग कर सकते हैं:

#define is_type_signed(my_type) (((my_type)-1) < 0) 
+3

इसे 'कॉन्स्ट बूल' कहने के बजाए मैक्रो क्यों बनाते हैं? –

+0

@ किथ थॉम्पसन यह अधिक "सार्वभौमिक" निर्माण है, न कि केवल चार प्रकार के लिए। –

+2

'numeric_limits <> :: is_signed' पहले से ही" सार्वभौमिकता "के किसी भी भाव को कवर करता है जिसे आप व्यक्त करने की कोशिश कर रहे हैं। – jxh

0

unsigned char का उपयोग करते हुए "हमेशा" आप कुछ दिलचस्प आश्चर्य दे सकता है , सी-स्टाइल फ़ंक्शन जैसे अधिकांश printf, fopen, char का उपयोग करेंगे, unsigned char नहीं।

संपादित करें: सी-शैली कार्यों के साथ "मजा" का उदाहरण:

const unsigned char *cmd = "grep -r blah *.txt"; 
FILE *pf = popen(cmd, "r"); 

त्रुटियों (वास्तव में, मैं *cmd = लाइन के लिए, और popen लाइन के लिए एक त्रुटि मिलती है) दे देंगे। const char *cmd = ... का उपयोग ठीक काम करेगा। मैं popen उठाया है क्योंकि यह एक समारोह है कि कुछ मानक सी ++ कार्यक्षमता के साथ बदलने के लिए तुच्छ नहीं है - जाहिर है, printf या fopen काफी आसानी से कुछ iostream या fstream प्रकार कार्यक्षमता, जो आम तौर पर विकल्प है कि unsigned char के साथ-साथ char लेने के साथ बदला जा सकता है।

हालांकि, अगर आप अक्षर हैं जो 127 से बाहर हैं पर > या < उपयोग कर रहे हैं, तो आप unsigned char उपयोग करने के लिए (या ऐसे int के कास्टिंग और कम 8 बिट मास्किंग रूप में कुछ अन्य समाधान है,) की आवश्यकता होगी।प्रत्यक्ष तुलना से बचने की कोशिश करना शायद बेहतर होता है (विशेष रूप से जब यह गैर-ASCII वर्णों की बात आती है - वे वैसे भी गन्दा होते हैं, क्योंकि लोकेल, चरित्र एन्कोडिंग आदि के आधार पर अक्सर कई प्रकार होते हैं)। समानता के लिए तुलना करना हालांकि काम करना चाहिए।

+0

@chux: संपादित करें ... –

+0

@chux: संपादन समाप्त नहीं हुआ था ... (स्वयं को नोट करें: पहले संपादित करें लिखें, फिर "संपादन देखें" कहने के लिए टिप्पणी करें) –

0

हां, यदि आप char प्रकार का उपयोग करना चाहते हैं और आप हमेशा इसे हस्ताक्षरित करना चाहते हैं, तो unsigned char का उपयोग करें। ध्यान दें कि अन्य मौलिक पूर्णांक प्रकारों के विपरीत, unsigned charchar से एक अलग प्रकार है - यहां तक ​​कि उन सिस्टम पर भी जहां char हस्ताक्षरित है। इसके अलावा, char से intought to be lossless से रूपांतरण इसलिए यदि आपका परिणाम गलत है, तो आपका स्रोत char मान भी गलत हो सकता है।

char पर हस्ताक्षर किए जाने का सबसे साफ तरीका यह है कि क्या आपको प्रीप्रोसेसर परीक्षण होने की आवश्यकता है और सी ++ के किस संस्करण पर आप लक्ष्यीकरण कर रहे हैं इस पर निर्भर करता है।

सशर्त एक पूर्वप्रक्रमक परीक्षण का उपयोग कर कोड संकलन करने के लिए, CHAR_MIN का मूल्य काम करना चाहिए:

#include <climits> 

#if (CHAR_MIN==0) 
// code that relies on char being unsigned 
#endif 

सी ++ 17 में, मैं प्रयोग करेंगे std::is_signed_v और std::is_unsigned_v:

#include <type_traits> 

static_assert(std::is_unsigned_v<char>); 
// code that relies on char being unsigned 

आप कर रहे हैं सी ++ 11 या सी ++ 14 के खिलाफ लिखने के लिए आपको थोड़ी अधिक वर्बोज़ std::is_signed और std::is_unsigned:

#include <type_traits> 

static_assert(std::is_unsigned<char>::value, "char is signed"); 
// code that relies on char being unsigned 

सी ++ के सभी संशोधनों के लिए, @ बेंजामिन-लिंडली का समाधान एक अच्छा विकल्प है।

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