2009-03-17 11 views
49

बाइट्स के बफर को चार या हस्ताक्षरित चार या बस एक चार बफर पर हस्ताक्षर किया जाना चाहिए? सी और सी ++ के बीच कोई अंतर?बाइट्स का बफर हस्ताक्षरित या हस्ताक्षरित चार बफर होना चाहिए?

धन्यवाद।

+0

https://stackoverflow.com/questions/13819820/ – kebs

उत्तर

26

बाइट्स की एक बफर चार या अहस्ताक्षरित चार या बस एक चार बफर हस्ताक्षर किया जाना चाहिए? सी और सी ++ के बीच कोई अंतर?

भाषा का व्यवहार कैसे करता है इसमें एक मामूली अंतर। एक विशाल इस बात का अंतर कैसे है कि सम्मेलन इसका व्यवहार करता है।

  • char = ASCII (या UTF-8, लेकिन signedness वहाँ रास्ते में हो जाता है) शाब्दिक डेटा
  • unsigned char = बाइट
  • signed char = शायद ही कभी

इस्तेमाल किया और वहाँ है कोड जो इस तरह के भेद पर पर निर्भर करता है। बस एक हफ्ते या दो बार मुझे एक बग का सामना करना पड़ा जहां जेपीईजी डेटा दूषित हो रहा था क्योंकि इसे हमारे बेस 64 एन्कोड फ़ंक्शन — के char* संस्करण में पारित किया जा रहा था, जो "स्ट्रिंग" में सभी अमान्य यूटीएफ -8 को "सहायक" रूप से बदल दिया गया था। BYTE उर्फ ​​unsigned char पर बदलना इसे ठीक करने के लिए लिया गया था।

+5

तो सी ++ iostreams 'read' और' write' विधियों के माध्यम से बाइनरी धाराओं को पढ़ने और लिखते समय डेटा बफर का प्रतिनिधित्व करने के लिए 'हस्ताक्षरित char *' के बजाय 'char *' का उपयोग क्यों करते हैं? : पी – BarbaraKwarc

+1

हस्ताक्षरित चार शायद ही कभी नहीं है। जेएनआई (जावा मूल इंटरफ़ेस, एनडीके 14.1) में, हस्ताक्षरित चार को जेबीटी के रूप में परिभाषित किया जाता है। – r0ng

+3

wtf जावा को इसके साथ क्या करना है (यूघ) – developerbmw

0

यदि आप एक व्यापक चर में तत्व प्राप्त करते हैं, तो यह निश्चित रूप से साइन-विस्तारित होगा या नहीं।

0

चाहिए और ... मैं करते हैं चाहिए अहस्ताक्षरित को पसंद करते हैं, क्योंकि यह महसूस करता है और अधिक "कच्चे", कम कहने के लिए "हे, कि सिर्फ छोटे ints का एक समूह है", अगर मैं द्विआधारी जोर देना चाहते आमंत्रित डेटा की गुणवत्ता।

मुझे नहीं लगता कि मैंने बाइट्स के बफर का प्रतिनिधित्व करने के लिए कभी भी एक स्पष्ट signed char का उपयोग किया है।

बेशक, एक तिहाई विकल्प बफर को void * जितना संभव हो उतना प्रतिनिधित्व करना है। कई सामान्य I/O फ़ंक्शंस void * के साथ काम करते हैं, इसलिए कभी-कभी पूर्णांक प्रकार का उपयोग करने का निर्णय पूरी तरह से encapsulated किया जा सकता है, जो अच्छा है।

+1

के साथ डुप्पी समस्या यह है कि आप इसे प्रचारित किए बिना चार का उपयोग नहीं कर सकते हैं। (चार) 0xFF! = (हस्ताक्षरित चार) 0xFF। बाइट समान हैं लेकिन वे बराबर की तुलना नहीं करते हैं। –

4

इसे बिना हस्ताक्षरित चार के रूप में परिभाषित करना बेहतर है। असर Win32 प्रकार BYTE को हस्ताक्षरित चार के रूप में परिभाषित किया गया है। इसके बीच सी & सी ++ के बीच कोई अंतर नहीं है।

+1

सामान्य विवरण साबित करने के लिए किसी विशेष मामले (Win32) का उपयोग करना सबसे अच्छा विचार नहीं है। – BarbaraKwarc

0

कई साल पहले मुझे एक सी ++ कंसोल एप्लिकेशन के साथ समस्या थी जो 128 से ऊपर ASCII मानों के लिए रंगीन वर्ण मुद्रित करता था और इसे चार से हस्ताक्षरित चार में स्विच करके हल किया गया था, लेकिन मुझे लगता है कि यह चार प्रकार को रखते हुए हल करने योग्य था ।

अभी के लिए, अधिकांश सी/सी ++ फ़ंक्शन char का उपयोग करते हैं और मैं दोनों भाषाओं को अब बेहतर समझता हूं, इसलिए मैं ज्यादातर मामलों में char का उपयोग करता हूं।

12

यह निर्भर करता है।

यदि बफर का पाठ रखने का इरादा है, तो शायद इसे char की सरणी के रूप में घोषित करने का अर्थ हो और प्लेटफॉर्म को आपके लिए तय करने दें कि क्या यह डिफ़ॉल्ट रूप से हस्ताक्षरित या हस्ताक्षरित है या नहीं। इससे आपको कार्यान्वयन की रनटाइम लाइब्रेरी में और बाहर डेटा को पार करने में कम से कम परेशानी होगी, उदाहरण के लिए।

यदि बफर का उद्देश्य बाइनरी डेटा धारण करना है, तो यह इस बात पर निर्भर करता है कि आप इसका उपयोग कैसे करना चाहते हैं। उदाहरण के लिए, यदि बाइनरी डेटा वास्तव में डेटा नमूने का एक पैक सरणी है जो 8-बिट निश्चित बिंदु एडीसी माप पर हस्ताक्षरित है, तो signed char सबसे अच्छा होगा।

अधिकांश वास्तविक दुनिया के मामलों में, बफर बस एक बफर है, और आप वास्तव में व्यक्तिगत बाइट्स के प्रकारों की परवाह नहीं करते हैं क्योंकि आपने बफर को थोक ऑपरेशन में भर दिया है, और आप पास होने वाले हैं जटिल डेटा संरचना की व्याख्या करने और कुछ उपयोगी करने के लिए यह एक पार्सर से बाहर है। उस स्थिति में, इसे सबसे सरल तरीके से घोषित करें।

0

क्या आपको वाकई परवाह है? यदि आप नहीं करते हैं, तो बस डिफ़ॉल्ट (char) का उपयोग करें और अपने कोड को महत्वहीन मामले के साथ अव्यवस्थित न करें। अन्यथा, भविष्य के रखरखावकर्ताओं को आश्चर्य होगा कि आपने हस्ताक्षरित (या हस्ताक्षरित) का उपयोग क्यों किया था। अपने जीवन को आसान बनाओ।

+5

मैं सहमत नहीं हूं। अगर मुझे (हस्ताक्षरित) वर्णों की एक श्रृंखला का सामना करना पड़ता है, तो मुझे लगता है कि यह किसी भी तरह से पाठ डेटा रखता है। –

+1

डेव वीडीई – dcw

+1

के साथ सहमत हैं और क्यों चार सरणी को टेक्स्ट डेटा को हस्ताक्षर नहीं किया जा सकता है? सादा चार डिफ़ॉल्ट हस्ताक्षर आर्किटेक्चर के बीच अलग है, लेकिन स्ट्रिंग कार्यों के libc हस्ताक्षर अभी भी वही हैं। –

9

यदि यह वास्तव में मशीन के डिफ़ॉल्ट लोकेल में एक स्ट्रिंग के बजाय 8 बिट बाइट्स का बफर है, तो मैं uint8_t का उपयोग करूंगा। ऐसा नहीं है कि चारों ओर कई मशीनें हैं जहां एक चार बाइट नहीं है (या एक बाइट एक ऑक्टेट) है, लेकिन 'यह एक स्ट्रिंग' के बजाय 'यह एक स्ट्रिंग' है, यह बयान बनाते हुए अक्सर उपयोगी दस्तावेज होता है।

+0

मैं इस माध्यम से रहा हूं, और यह सिद्धांत में अच्छा लगता है, लेकिन यदि आप इस डेटा को मानक सी या POSIX फ़ंक्शन (फ़ाइल/सॉकेट पढ़ने/लिखने) में पास करते हैं तो यह बहुत परेशानी पैदा करता है। –

+4

पॉज़िक्स पढ़ें/लिखना एक शून्य * बफर ले लो। POSIX फ़ंक्शंस जो char * की अपेक्षा करता है (उदाहरण के लिए पथ तर्क() को खोलने के लिए) एक स्ट्रिंग की अपेक्षा करता है, बाइट बफर नहीं। –

3

अधिकतम पोर्टेबिलिटी के लिए हमेशा हस्ताक्षरित char का उपयोग करें।ऐसे कुछ उदाहरण हैं जहां यह खेल सकता है। अलग-अलग एंडियन प्रकार वाले सिस्टम में साझा किए गए सीरियलाइज्ड डेटा को तुरंत दिमाग में आता है। जब शिफ्ट या बिट मास्किंग करते हैं तो मान एक और है।

5

आप या तो चार या अहस्ताक्षरित चार लेकिन चार कभी नहीं पर हस्ताक्षर किए उपयोग करना चाहिए। मानक 3,9/2

में निम्नलिखित किसी भी वस्तु पॉड प्रकार टी, की (एक आधार स्तरीय subobject के अलावा अन्य) है या नहीं, ऑब्जेक्ट प्रकार टी के एक मान्य मान रखती है के लिए है, अंतर्निहित बाइट्स (1.7) वस्तु बनाने चार या अहस्ताक्षरित char.If चार या अहस्ताक्षरित चार की सरणी वस्तु में वापस नकल की सामग्री की एक सरणी में कॉपी किया जा सकता, वस्तु बाद में पकड़ जाएगा इसकी मूल मूल्य।

47

आप मनमाने ढंग से बाइनरी डेटा स्टोर करने के लिए करना चाहते हैं, तो आप unsigned char उपयोग करना चाहिए। यह एकमात्र डेटा प्रकार है जिसे सी मानक द्वारा कोई पैडिंग बिट्स की गारंटी नहीं है। प्रत्येक अन्य डेटा प्रकार में ऑब्जेक्ट प्रस्तुति में पैडिंग बिट्स हो सकते हैं (वह वह है जिसमें ऑब्जेक्ट के सभी बिट्स होते हैं, केवल वे मानते हैं जो मूल्य निर्धारित करते हैं)। पैडिंग बिट्स 'राज्य अनिर्दिष्ट है और मूल्यों को स्टोर करने के लिए उपयोग नहीं किया जाता है। तो यदि आप char का उपयोग कुछ बाइनरी डेटा का उपयोग करके पढ़ते हैं, तो चीजों को एक चर की मान सीमा में घटाया जाएगा (केवल मूल्य बिट्स को समझकर), लेकिन अभी भी बिट्स हो सकते हैं जिन्हें अभी अनदेखा किया गया है लेकिन अभी भी वहां हैं और memcpy द्वारा पढ़े गए हैं। असली संरचना वस्तुओं में पैडिंग बिट्स की तरह। टाइप unsigned char उनको शामिल करने की गारंटी नहीं है। यही कारण है कि 5.2.4.2.1/2 (C99 TC2, n1124 यहाँ) से इस प्रकार है:

जब एक अभिव्यक्ति में प्रयोग किया जाता है, तो प्रकार चार की एक वस्तु के मूल्य में एक हस्ताक्षरित पूर्णांक के रूप में व्यवहार किया जाता है, CHAR_MIN का मूल्य उस के रूप में ही किया जाएगा SCHAR_MIN और CHAR_MAX का मान SCHAR_MAX जैसा ही होगा। अन्यथा, CHAR_MIN का मान 0 होगा और CHAR_MAX का मान UCHAR_MAX जैसा ही होगा। मूल्य UCHAR_MAX अंतिम वाक्य यह इस प्रकार कोई जगह नहीं किसी भी गद्दी बिट्स के लिए छोड़ दिया है कि वहां से बराबर होगा 2^CHAR_BIT − 1

। यदि आप char का उपयोग अपने बफर के प्रकार के रूप में करते हैं, तो आपको ओवरफ़्लो की समस्या भी होती है: 8 बिट्स की सीमा में किसी भी तत्व को स्पष्ट रूप से किसी भी मान को असाइन करना - ताकि आप इस तरह के असाइनमेंट को ठीक होने की उम्मीद कर सकें - लेकिन भीतर नहीं char की सीमा, जो CHAR_MIN है .. CHAR_MAX, ऐसे रूपांतरण ओवरफ्लो और सिग्नल बढ़ाने सहित कार्यान्वयन परिभाषित परिणामों का कारण बनता है।

यहां तक ​​कि अगर इसके बाद के संस्करण के बारे में किसी भी समस्याओं शायद वास्तविक कार्यान्वयन में नहीं दिखाया जाएगा (एक कार्यान्वयन के बहुत खराब गुणवत्ता होगा), आप सबसे अच्छा के बाद शुरुआत है, जो unsigned char है से सही प्रकार का उपयोग कर रहे हैं।

तारों के लिए, हालांकि, डेटा प्रकार का विकल्प char है, जिसे स्ट्रिंग और प्रिंट फ़ंक्शंस द्वारा समझा जाएगा।इन उद्देश्यों के लिए signed char का उपयोग करना मेरे लिए गलत निर्णय जैसा दिखता है।

अधिक जानकारी के लिए, this proposal पढ़ें जिसमें सी मानक के अगले संस्करण के लिए एक फिक्स शामिल है जिसके अंत में signed char की आवश्यकता होगी या तो कोई पैडिंग बिट्स न हो। यह पहले से ही working paper में शामिल है।

+0

बी-लेकिन सी 99 6.2.6.2 कहता है "हस्ताक्षरित चार में कोई पैडिंग बिट नहीं होगा" – Ivan

+7

सी भूल जाओ। [सी ++ 11: 3.9.1/1]: '[..] _ए चार, एक हस्ताक्षरित चार, और एक हस्ताक्षरित चार समान भंडारण पर कब्जा करते हैं और समान संरेखण आवश्यकताओं (3.11) हैं; यानी, उनके पास एक ही वस्तु का प्रतिनिधित्व है। चरित्र प्रकारों के लिए, ऑब्जेक्ट प्रस्तुति के सभी बिट्स मान प्रतिनिधित्व में भाग लेते हैं ._ [..] क्या यह सुझाव नहीं देता है कि _all तीन_ वर्ण प्रकारों में, कम से कम _same_ पैडिंग है? और मैं इसका अर्थ यह समझने के लिए करता हूं कि उनमें से कोई भी नहीं है। –

+0

(कृपया देखें http://stackoverflow.com/a/21176278/560648) –

2

int8_t बनाम uint8_t की पसंद समान है जब आप एक पीआरआर की तुलना नल की तुलना में कर रहे हैं।


देखने के एक कार्यक्षमता की दृष्टि से, शून्य की तुलना में 0 की तुलना के रूप में ही है, क्योंकि शून्य के लिए 0.

लेकिन व्यक्तिगत रूप से एक #define है, को देखने के एक कोडन शैली बिंदु से, मैं चुनें जब किसी को 0 पर एक तुलना देखता है शून्य करने के लिए अपने संकेत तुलना करने के लिए, क्योंकि शून्य #define कोड है कि आप एक बुरा सूचक के लिए जाँच कर रहे हैं बनाए रखने के व्यक्ति के लिए की ओर संकेत करता ...

वी.एस.

यह संकेत करता है कि आप कर रहे हैं एक विशिष्ट मूल्य की जांच।


उपरोक्त कारण से, मैं uint8_t का उपयोग करूंगा।

-1

यदि आप कंपाइलर से झूठ बोलते हैं, तो यह आपको दंडित करेगा।

यदि बफर में डेटा है जो बस गुजर रहा है, और आप उन्हें किसी भी तरह से कुशल नहीं करेंगे, इससे कोई फर्क नहीं पड़ता।

हालांकि, अगर आपको बफर सामग्री पर काम करना है तो सही प्रकार की घोषणा आपके कोड को सरल बना देगी। नहीं "int val = buf [i] & 0xff;" बकवास।

तो, इस बारे में सोचें कि वास्तव में डेटा क्या है और आपको इसका उपयोग करने की आवश्यकता है।

0
typedef char byte; 

अब आप अपनी सरणी byte एस बना सकते हैं। यह सब लोगों के लिए स्पष्ट है कि आपका क्या मतलब था, और आप कोई कार्यक्षमता खोना नहीं चाहते हैं।

मुझे पता है कि यह कुछ मूर्खतापूर्ण है, लेकिन यह आपके कोड को 100% पढ़ता है जैसा कि आप चाहते हैं।

+3

यह ** ** विंडोज प्रोग्रामर के लिए स्पष्ट नहीं है जिसका उपयोग 'टाइप किए गए चार BYTE' टाइप किया गया है। – dan04

+0

यह सवाल का उत्तर कैसे देता है? –

+3

अपने डोमेन में, वह इसे "बाइट्स का बफर" के रूप में संदर्भित करता है। अधिकतर प्रतिक्रियाएं उपलब्ध विकल्पों में अलग-अलग चीज़ों के बारे में बात करती हैं। मैंने समझाते हुए दृष्टिकोण लिया, "यदि आप इसे 'बाइट' के रूप में संदर्भित करते हैं, तो इसे इस तरह टाइप करना सर्वोत्तम हो सकता है।" 23 लोगों ने इसे एक दिलचस्प सवाल के रूप में उभारा, और 12 लोगों ने इसे देखा - यह चौंकाने वाला है। मैं इस बात से सहमत हूं कि मेरी पोस्ट उपयोगकर्ता के प्रश्न का उत्तर देने का प्रयास नहीं करती है, लेकिन मैं यह भी तर्क दूंगा कि अन्य उत्तरों यहां सॉफ्टवेयर विकास के एक पहलू को अनदेखा करते हैं जिसे मैं रोशनी देने का प्रयास कर रहा था: चीजों के प्रकार का नाम कैसे दें। –