मेमोरी में कुछ कच्चे डेटा को बफर करने की आवश्यकता है, उदाहरण के लिए स्ट्रीम से, क्या यह char या unsigned char की सरणी का उपयोग करना बेहतर है? मैं हमेशा char का उपयोग करता था लेकिन काम पर कह रहा था कि यह बेहतर हस्ताक्षरित चार है और मुझे नहीं पता क्यों ...कच्चे डेटा को संग्रहीत करने के लिए चार या हस्ताक्षरित चार सरणी का उपयोग करना बेहतर है?
उत्तर
अद्यतन: सी ++ 17 std::byte
पेश किया गया, जो char
के किसी भी तरीके का उपयोग करने से "कच्चे" डेटा बफर के लिए अधिक उपयुक्त है।
पहले सी ++ संस्करणों के लिए:
unsigned char
पर जोर देती है कि डेटा "बस" पाठआप मिल गया है, तो क्या उदा से "बाइट" डेटा को प्रभावी ढंग से नहीं है एक संपीड़ित धारा, एक डेटाबेस तालिका बैकअप फ़ाइल, एक निष्पादन योग्य छवि, एक jpeg ... तो
ऊपर उल्लेख किया बाइनरी डेटा अर्थunsigned
unsigned
आपरेशन आप करना चाह सकते हैं में से कुछ के लिए बेहतर काम करता है के लिए उपयुक्त है द्विआधारी डेटा पर करें, उदाहरण के लिए वहाँ पर हस्ताक्षर किए प्रकार पर कुछ बिट के संचालन के लिए अपरिभाषित और कार्यान्वयन परिभाषित व्यवहार कर रहे हैं, औरunsigned
मूल्यों सरणियोंमें सूचकांक के रूप में इस्तेमाल किया जा सकता अगर आप गलती से एक समारोह
char*
उम्मीद करने के लिए एकunsigned char*
पारित नहीं हो सकता और यह के रूप में पर संचालित है अनुमानित पाठइन स्थितियों में आमतौर पर मूल्यों के बारे में सोचने के लिए अधिक प्राकृतिक है 0..255, सभी के बाद - क्यों "साइन" बिट को अन्य बिट्स के लिए एक अलग तरह का महत्व होना चाहिए आँकड़े?
अगर आप भंडारण कर रहे हैं "कच्चे डेटा" है कि - एक आवेदन तर्क पर/डिजाइन के स्तर का तो हर तरह से चयन 8 बिट संख्यात्मक डेटा, होने वाला या तो
unsigned
या स्पष्टsigned
char
के रूप में उपयुक्त आपकी जरूरतों के लिए
आंतरिक रूप से, यह बिल्कुल वही है: प्रत्येक तत्व एक बाइट है। अंतर तब दिया जाता है जब आप उन मानों के साथ काम करते हैं।
यदि आपकी मान सीमा है [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 डिफ़ॉल्ट रूप से प्रोग्राम कार्य करने दें।
प्रकार चार हमेशा हस्ताक्षरित चार या हस्ताक्षरित चार से एक अलग प्रकार है, भले ही इसका व्यवहार हमेशा उन दोनों में से एक जैसा है।
से निपटने की आवश्यकता न हो, आपको लगता है कि 'char' हस्ताक्षरित है। तो "रेंज" और "ओवरफ्लो" भाग जरूरी नहीं हैं। –
"अगर यह है [-127,127] 'char' का उपयोग करें।" यदि आपको हस्ताक्षर की आवश्यकता है, तो 'char' को भी हस्ताक्षरित किया जा सकता है,' हस्ताक्षरित char' का उपयोग करें। "... आपको एक नकारात्मक संख्या दे।" शायद, शायद नहीं, हस्ताक्षर ओवरफ्लो यूबी है। –
@ बाममितएगेन यह सच है लेकिन उस मामले में ओपी को वांछित मूल्य प्राप्त करने की उम्मीद नहीं करनी चाहिए। –
यह आमतौर पर बेहतर है char
उपयोग करने के लिए लेकिन यह इतना कम अंतर यह कोई बात नहीं करता है। यह कच्चा डेटा है, इसलिए आपको इसे एक प्रकार या किसी अन्य के char
पॉइंटर्स के माध्यम से इसके साथ काम करने की कोशिश करने के बजाय बस इसे पास करना चाहिए। चूंकि char
मूल डेटा प्रकार है, यह कल्पना करने के बजाय कि आप अपने डेटा को एक प्रकार या दूसरे में मजबूर कर रहे हैं, इसका उपयोग करने के लिए सबसे अधिक समझदारी होती है।
जहां तक बफर की संरचना का संबंध है, इसमें कोई अंतर नहीं है: दोनों मामलों में आपको मानक द्वारा अनिवार्य एक बाइट का तत्व आकार मिलता है।
शायद आपको जो सबसे महत्वपूर्ण अंतर मिलता है वह वह व्यवहार है जिसे आप बफर के अलग-अलग तत्वों तक पहुंचते समय देखते हैं, उदाहरण के लिए, प्रिंटिंग के लिए।char
के साथ आपको कार्यान्वयन-परिभाषित हस्ताक्षरित या हस्ताक्षरित व्यवहार मिलता है; unsigned char
के साथ आप हमेशा हस्ताक्षरित व्यवहार देखते हैं। यह महत्वपूर्ण हो जाता है यदि आप अपने "कच्चे डेटा" बफर के व्यक्तिगत बाइट प्रिंट करना चाहते हैं।
बफर के लिए उपयोग के लिए एक और अच्छा विकल्प सटीक-चौड़ाई पूर्णांक uint8_t
है। यह unsigned char
के समान चौड़ाई रखने की गारंटी है, इसके नाम को कम टाइपिंग की आवश्यकता है, और यह पाठक को बताता है कि आप बफर के व्यक्तिगत तत्वों को वर्ण-आधारित जानकारी के रूप में उपयोग करने का इरादा नहीं रखते हैं।
यदि आप हस्ताक्षरित चार का उपयोग करते हैं तो यह केवल वैध ASCII वर्ण लेगा क्योंकि इसकी सीमा -127 से +127 हो जाएगी।
और आप इस प्रश्न में चार और हस्ताक्षरित चार विवरणों के बीच पूर्ण अंतर पा सकते हैं।
diff bet char and unsigned char
और आप तालिका यहाँ देख सकते हैं।
@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 दुनिया में, भेद कई मामलों में कोई फर्क नहीं पड़ता)। यह धुंधला हमेशा सहायक नहीं होता है, लेकिन यह आपके सिर में अंतर को स्पष्ट रखने के लिए कम से कम अच्छी बौद्धिक स्वच्छता है।
यदि आप सी ++ 17 के साथ काम करने में सक्षम हैं तो एक std :: बाइट प्रकार है जो कच्चे डेटा के साथ काम करने के लिए अधिक उपयुक्त है। इसके लिए केवल बिटवाई लॉजिक ऑपरेटरों को परिभाषित किया गया है।
- 1. परिवर्तित चार [] सरणी चार करने के लिए **
- 2. चार सरणी वी.एस. चार *
- 3. चार सरणी का संरेखण
- 4. सरणी सरणियों चार को
- 5. चार हस्ताक्षरित पूर्णांक (सी ++)
- 6. चार सरणी
- 7. चार सरणी बनाम चार सूचक
- 8. एक हस्ताक्षरित चार
- 9. हस्ताक्षरित चार का अधिकतम मूल्य
- 10. बाइट्स का बफर हस्ताक्षरित या हस्ताक्षरित चार बफर होना चाहिए?
- 11. चार सरणी
- 12. सी - चार सरणी
- 13. सी ++ में चार और हस्ताक्षरित चार के बीच अंतर?
- 14. चार सरणी सबस्क्रिप्ट चेतावनी
- 15. हस्ताक्षरित चार थ्रेड-सुरक्षित (परमाणु)
- 16. एक बूल एक हस्ताक्षरित चार क्यों है?
- 17. कुशलतापूर्वक एक हस्ताक्षरित शॉर्ट को चार *
- 18. strtok - बनाम चार सूचक चार सरणी
- 19. सी # स्ट्रिंग के लिए चार और चार सरणी असाइन करें?
- 20. फ़ंक्शन में चार सरणी पास करना?
- 21. सी चार को चार *
- 22. स्ट्रिंग सामग्री को चार सरणी
- 23. चार ** बनाम चार * सी [] स्ट्रिंग सरणी
- 24. सी ++, एक चार सरणी
- 25. अहस्ताक्षरित चार में कनवर्ट कर चार * *
- 26. चार के
- 27. जावा चार सरणी int
- 28. एक चार सरणी के हेक्साडेसिमल प्रतिनिधित्व को मुद्रित करना []
- 29. चार सरणी से बूल
- 30. एक चार सरणी
यदि यह स्ट्रिंग स्ट्रीम है तो यह 'char' सरणी का उपयोग करना ठीक होगा। अन्य संख्यात्मक (उदाहरण के लिए, हेक्साडेसिमल, बिट्स) कच्चे डेटा के लिए, 'हस्ताक्षरित' चर का उपयोग करना सबसे अच्छा है ताकि आपको साइन बिट –