2014-06-12 4 views
5

मेमोरी में कुछ कच्चे डेटा को बफर करने की आवश्यकता है, उदाहरण के लिए स्ट्रीम से, क्या यह char या unsigned char की सरणी का उपयोग करना बेहतर है? मैं हमेशा char का उपयोग करता था लेकिन काम पर कह रहा था कि यह बेहतर हस्ताक्षरित चार है और मुझे नहीं पता क्यों ...कच्चे डेटा को संग्रहीत करने के लिए चार या हस्ताक्षरित चार सरणी का उपयोग करना बेहतर है?

+0

यदि यह स्ट्रिंग स्ट्रीम है तो यह 'char' सरणी का उपयोग करना ठीक होगा। अन्य संख्यात्मक (उदाहरण के लिए, हेक्साडेसिमल, बिट्स) कच्चे डेटा के लिए, 'हस्ताक्षरित' चर का उपयोग करना सबसे अच्छा है ताकि आपको साइन बिट –

उत्तर

8

अद्यतन: सी ++ 17 std::byte पेश किया गया, जो char के किसी भी तरीके का उपयोग करने से "कच्चे" डेटा बफर के लिए अधिक उपयुक्त है।

पहले सी ++ संस्करणों के लिए:

  • unsigned char पर जोर देती है कि डेटा "बस" पाठ

  • आप मिल गया है, तो क्या उदा से "बाइट" डेटा को प्रभावी ढंग से नहीं है एक संपीड़ित धारा, एक डेटाबेस तालिका बैकअप फ़ाइल, एक निष्पादन योग्य छवि, एक jpeg ... तो unsigned

    ऊपर उल्लेख किया बाइनरी डेटा अर्थ
    • unsigned आपरेशन आप करना चाह सकते हैं में से कुछ के लिए बेहतर काम करता है के लिए उपयुक्त है द्विआधारी डेटा पर करें, उदाहरण के लिए वहाँ पर हस्ताक्षर किए प्रकार पर कुछ बिट के संचालन के लिए अपरिभाषित और कार्यान्वयन परिभाषित व्यवहार कर रहे हैं, और unsigned मूल्यों सरणियों

    • में सूचकांक के रूप में इस्तेमाल किया जा सकता अगर आप गलती से एक समारोह char* उम्मीद करने के लिए एक unsigned char* पारित नहीं हो सकता और यह के रूप में पर संचालित है अनुमानित पाठ

    • इन स्थितियों में आमतौर पर मूल्यों के बारे में सोचने के लिए अधिक प्राकृतिक है 0..255, सभी के बाद - क्यों "साइन" बिट को अन्य बिट्स के लिए एक अलग तरह का महत्व होना चाहिए आँकड़े?

  • अगर आप भंडारण कर रहे हैं "कच्चे डेटा" है कि - एक आवेदन तर्क पर/डिजाइन के स्तर का तो हर तरह से चयन 8 बिट संख्यात्मक डेटा, होने वाला या तो unsigned या स्पष्टsignedchar के रूप में उपयुक्त आपकी जरूरतों के लिए

3

आंतरिक रूप से, यह बिल्कुल वही है: प्रत्येक तत्व एक बाइट है। अंतर तब दिया जाता है जब आप उन मानों के साथ काम करते हैं।

यदि आपकी मान सीमा है [0,255] तो आपको unsigned char का उपयोग करना चाहिए, लेकिन यदि यह [-128,127] है तो आपको signed char का उपयोग करना चाहिए।

मान लें कि आप पहली श्रेणी (signed char) का उपयोग कर रहे हैं, तो आप ऑपरेशन 100+100 कर सकते हैं। अन्यथा वह ऑपरेशन बह जाएगा और आपको एक अप्रत्याशित मूल्य देगा।

अपने संकलक या मशीन प्रकार के आधार पर char डिफ़ॉल्ट रूप से अहस्ताक्षरित या हस्ताक्षर किए हो सकता है: Is char signed or unsigned by default? इस प्रकार char पर्वतमाला ऊपर मामलों के लिए वर्णित है।

यदि आप इस बफर का उपयोग केवल इसके साथ काम किए बिना बाइनरी डेटा स्टोर करने के लिए कर रहे हैं, तो char या unsigned char का उपयोग करने के बीच कोई अंतर नहीं है।

संपादित

ध्यान दें कि आप भी change the defaultchar एक ही मशीन और संकलक का उपयोग कर संकलक के झंडे के लिए कर सकते हैं: प्रकार चार अहस्ताक्षरित हो

-funsigned-चार , अहस्ताक्षरित चार तरह।

प्रत्येक प्रकार की मशीन के लिए डिफ़ॉल्ट होना चाहिए कि चार क्या होना चाहिए। यह या तो डिफॉल्ट रूप से चारों ओर charinsigned या डिफ़ॉल्ट रूप से हस्ताक्षरित चार की तरह है। आदर्श रूप से, एक पोर्टेबल प्रोग्राम हमेशा किसी ऑब्जेक्ट की हस्ताक्षर पर निर्भर करता है जब हस्ताक्षरित चार या हस्ताक्षरित char का उपयोग करना चाहिए। लेकिन कई प्रोग्राम सादे चार का उपयोग करने के लिए लिखे गए हैं और पर हस्ताक्षर किए जाने की उम्मीद है, या मशीनों के आधार पर हस्ताक्षरित होने की उम्मीद है। यह विकल्प, और इसके विपरीत, आपको विपरीत 0 डिफ़ॉल्ट रूप से प्रोग्राम कार्य करने दें।

प्रकार चार हमेशा हस्ताक्षरित चार या हस्ताक्षरित चार से एक अलग प्रकार है, भले ही इसका व्यवहार हमेशा उन दोनों में से एक जैसा है।

+1

से निपटने की आवश्यकता न हो, आपको लगता है कि 'char' हस्ताक्षरित है। तो "रेंज" और "ओवरफ्लो" भाग जरूरी नहीं हैं। –

+2

"अगर यह है [-127,127] 'char' का उपयोग करें।" यदि आपको हस्ताक्षर की आवश्यकता है, तो 'char' को भी हस्ताक्षरित किया जा सकता है,' हस्ताक्षरित char' का उपयोग करें। "... आपको एक नकारात्मक संख्या दे।" शायद, शायद नहीं, हस्ताक्षर ओवरफ्लो यूबी है। –

+0

@ बाममितएगेन यह सच है लेकिन उस मामले में ओपी को वांछित मूल्य प्राप्त करने की उम्मीद नहीं करनी चाहिए। –

0

यह आमतौर पर बेहतर है char उपयोग करने के लिए लेकिन यह इतना कम अंतर यह कोई बात नहीं करता है। यह कच्चा डेटा है, इसलिए आपको इसे एक प्रकार या किसी अन्य के char पॉइंटर्स के माध्यम से इसके साथ काम करने की कोशिश करने के बजाय बस इसे पास करना चाहिए। चूंकि char मूल डेटा प्रकार है, यह कल्पना करने के बजाय कि आप अपने डेटा को एक प्रकार या दूसरे में मजबूर कर रहे हैं, इसका उपयोग करने के लिए सबसे अधिक समझदारी होती है।

4

जहां तक ​​बफर की संरचना का संबंध है, इसमें कोई अंतर नहीं है: दोनों मामलों में आपको मानक द्वारा अनिवार्य एक बाइट का तत्व आकार मिलता है।

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

बफर के लिए उपयोग के लिए एक और अच्छा विकल्प सटीक-चौड़ाई पूर्णांक uint8_t है। यह unsigned char के समान चौड़ाई रखने की गारंटी है, इसके नाम को कम टाइपिंग की आवश्यकता है, और यह पाठक को बताता है कि आप बफर के व्यक्तिगत तत्वों को वर्ण-आधारित जानकारी के रूप में उपयोग करने का इरादा नहीं रखते हैं।

0

यदि आप हस्ताक्षरित चार का उपयोग करते हैं तो यह केवल वैध ASCII वर्ण लेगा क्योंकि इसकी सीमा -127 से +127 हो जाएगी।

और आप इस प्रश्न में चार और हस्ताक्षरित चार विवरणों के बीच पूर्ण अंतर पा सकते हैं।

diff bet char and unsigned char

और आप तालिका यहाँ देख सकते हैं।

ASCII table

complete tables of raw characters

1

@Pablo के रूप में अपने जवाब में कहा, प्रमुख कारण है कि अगर आप बाइट्स पर गणित कर रहे हैं, अगर आप की घोषणा 'सही' जवाब मिल जाएगा है unsigned char के रूप में बाइट्स: आप चाहते हैं (पाब्लो के उदाहरण में) 100 + 100 200 में जोड़ने के लिए; यदि आप signed char के साथ यह योग करते हैं (यदि आप अपने कंपाइलर पर char पर हस्ताक्षर किए हैं तो दुर्घटना से हो सकता है) इसकी कोई गारंटी नहीं है - आप परेशानी के लिए पूछ रहे हैं।

एक अन्य महत्वपूर्ण कारण यह है कि यह आपके कोड को दस्तावेज़ में मदद कर सकता है, अगर आप स्पष्ट हैं कि डेटाटाइप क्या हैं। यह घोषणा करने के लिए

typedef unsigned char byte 

या और भी बेहतर

#include <stdint.h> 
typedef uint8_t byte 

byte का उपयोग करते हुए उसके बाद बनाता है उपयोगी है यह है कि छोटा सा स्पष्ट क्या अपने कार्यक्रम की मंशा है। कैसे पागल अपने संकलक है पर निर्भर करता है (-Wall अपने दोस्त है), इस भी एक प्रकार की चेतावनी यदि आप एक char* समारोह तर्क के लिए एक byte* तर्क देना इस प्रकार आप थोड़ा और अधिक आप कर रहे हैं कि क्या बारे में सावधानीपूर्वक विचार करने का संकेत देने के कारण हो सकता, सही बात।

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

0

यदि आप सी ++ 17 के साथ काम करने में सक्षम हैं तो एक std :: बाइट प्रकार है जो कच्चे डेटा के साथ काम करने के लिए अधिक उपयुक्त है। इसके लिए केवल बिटवाई लॉजिक ऑपरेटरों को परिभाषित किया गया है।

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