C / C ++ में, किसके unsigned charलिए प्रयोग किया जाता है? यह एक नियमित से कैसे अलग है char?
C / C ++ में, किसके unsigned charलिए प्रयोग किया जाता है? यह एक नियमित से कैसे अलग है char?
जवाबों:
C ++ में, तीन अलग-अलग वर्ण प्रकार हैं:
charsigned charunsigned charयदि आप पाठ के लिए वर्ण प्रकार का उपयोग कर रहे हैं , तो अयोग्य का उपयोग करें char:
'a'या '0'।"abcde"यह संख्या मान के रूप में भी काम करता है, लेकिन यह अनिर्दिष्ट है कि क्या उस मूल्य को हस्ताक्षरित या अहस्ताक्षरित माना जाता है। असमानताओं के माध्यम से चरित्र की तुलना से सावधान रहें - यदि आप खुद को ASCII (0-127) तक सीमित रखते हैं तो आप सुरक्षित हैं।
यदि आप वर्ण प्रकारों को संख्याओं के रूप में उपयोग कर रहे हैं , तो उपयोग करें:
signed char, जो आपको कम से कम -127 से 127 रेंज देता है। (-128 से 127 आम है)unsigned char, जो आपको कम से कम 0 से 255 की रेंज देता है।"कम से कम", क्योंकि सी ++ मानक केवल उन मूल्यों की न्यूनतम सीमा देता है जिन्हें कवर करने के लिए प्रत्येक संख्यात्मक प्रकार की आवश्यकता होती है। sizeof (char)1 (यानी एक बाइट) होना आवश्यक है, लेकिन सिद्धांत में एक बाइट उदाहरण के लिए 32 बिट्स हो सकता है। sizeofअभी भी इसके आकार की रिपोर्ट होगी1 - जिसका अर्थ है कि आपके पास हो सकता है sizeof (char) == sizeof (long) == 1।
sizeofएक समारोह के लिए एक जगह नहीं है क्योंकि यह एक समारोह लेकिन एक ऑपरेटर है आम है । एक चर का आकार लेते समय कोष्ठक को छोड़ना बेहतर शैली है। sizeof *pया sizeof (int)। यदि यह एक प्रकार या चर पर लागू होता है, तो यह जल्दी से स्पष्ट हो जाता है। इसी तरह, बाद में कोष्ठक लगाना भी बेमानी है return। यह एक समारोह नहीं है।
char: यह चरित्र के प्रकार का शाब्दिक है जैसे 'a'या '0'।" C ++ में सही है लेकिन C में C नहीं है, a 'a'है int।
यह कार्यान्वयन निर्भर है, क्योंकि C मानक हस्ताक्षरित-नेस को परिभाषित नहीं करता है char। प्लेटफ़ॉर्म के आधार पर, हो सकता है signedया unsigned, इसलिए आपको स्पष्ट रूप से पूछने की आवश्यकता है signed charया unsigned charयदि आपका कार्यान्वयन इस पर निर्भर करता है। charयदि आप स्ट्रिंग्स से वर्णों का प्रतिनिधित्व करने का इरादा रखते हैं तो इसका उपयोग करें , क्योंकि यह मेल खाएगा कि आपका मंच स्ट्रिंग में क्या डालता है।
के बीच का अंतर signed charऔर unsigned charआपकी अपेक्षा है। सबसे प्लेटफार्मों पर, signed charएक 8 बिट दो के पूरक से लेकर नंबर होगा -128करने के लिए 127, और unsigned char(एक 8 बिट अहस्ताक्षरित पूर्णांक हो जाएगा 0करने के लिए 255)। ध्यान दें कि मानक की आवश्यकता नहीं है कि charप्रकारों में 8 बिट्स हैं, केवल उस sizeof(char)वापसी 1। आप के साथ एक चार में बिट्स की संख्या में प्राप्त कर सकते हैं CHAR_BITमें limits.h। हालांकि अगर कोई प्लेटफॉर्म आज भी मौजूद है तो इसके अलावा कुछ और भी होंगे 8।
यहाँ इस मुद्दे का एक अच्छा सारांश है ।
जैसा कि दूसरों ने उल्लेख किया है कि मैंने इसे पोस्ट किया है, आप का उपयोग करना बेहतर है int8_tऔर uint8_tयदि आप वास्तव में छोटे पूर्णांक का प्रतिनिधित्व करना चाहते हैं।
CHAR_BITमानक द्वारा कम से कम 8 बिट होना आवश्यक है।
क्योंकि मुझे लगता है कि यह वास्तव में कहा जाता है, मैं सी और सी ++ के कुछ नियमों को बताना चाहता हूं (वे इस संबंध में समान हैं)। सबसे पहले, सभी बिट्स के unsigned charमूल्य यदि कोई अहस्ताक्षरित चार वस्तु का निर्धारण करने में भाग लेते हैं। दूसरा, unsigned charस्पष्ट रूप से अहस्ताक्षरित बताया गया है।
अब, मैंने किसी के साथ इस बारे में चर्चा की कि क्या होता है जब आप -1टाइप के मूल्य को इंट में बदल देते हैं unsigned char। उन्होंने इस विचार से इनकार कर दिया कि जिसके परिणामस्वरूप unsigned charउसके सभी बिट्स 1 पर सेट हो गए हैं, क्योंकि वह साइन प्रतिनिधित्व के बारे में चिंतित था। लेकिन वह नहीं है। यह इस नियम के तुरंत बाद है कि रूपांतरण वह करता है जो इरादा है:
यदि नया प्रकार अहस्ताक्षरित है, तो मूल्य बार-बार जोड़कर या घटाकर अधिकतम मूल्य से एक बार घटाया जाता है जो नए प्रकार में तब तक प्रस्तुत किया जा सकता है जब तक कि मूल्य नए प्रकार की सीमा में न हो। (
6.3.1.3p2एक C99 ड्राफ्ट में)
यह एक गणितीय विवरण है। C ++ इसे मॉडुलो कैलकुलस के संदर्भ में बताता है, जो एक ही नियम के लिए पैदावार देता है। वैसे भी, जो गारंटी नहीं है वह यह है कि पूर्णांक के सभी बिट्स -1रूपांतरण से पहले एक हैं। तो, हमारे पास ऐसा क्या है जिससे हम यह दावा कर सकते हैं कि परिणामस्वरूप unsigned charइसके सभी CHAR_BITबिट्स 1 हो गए हैं?
UCHAR_MAX+1के लिए -1रेंज में एक मूल्य निकलेगा, अर्थात्UCHAR_MAXवास्तव में इतना ही काफी है! तो जब भी आप unsigned charअपने सभी बिट्स एक होना चाहते हैं, तो आप करते हैं
unsigned char c = (unsigned char)-1;
यह इस प्रकार भी है कि रूपांतरण केवल उच्च क्रम बिट्स को छोटा नहीं कर रहा है। दो के पूरक के लिए सौभाग्यशाली घटना यह है कि यह सिर्फ वहाँ एक छंटनी है, लेकिन अन्य संकेत प्रतिनिधित्वों के लिए भी यह सच नहीं है।
UCHAR_MAX?
(unsigned type)-1किसी तरह का मुहावरा है। ~0नहीं है।
int x = 1234और char *y = &x। का बाइनरी प्रतिनिधित्व 1234 है 00000000 00000000 00000100 11010010। मेरी मशीन थोड़ा एंडियन है इसलिए यह इसे उलट देती है और मेमोरी 11010010 00000100 00000000 00000000एलएसबी में स्टोर हो जाती है । अब मेन पार्ट। अगर मैं का उपयोग printf("%d" , *p)। printfपहली बाइट पढ़ा जाएगा 11010010केवल उत्पादन होता है -46लेकिन 11010010है 210तो क्यों इसे प्रिंट करता है -46। मैं वास्तव में उलझन में हूँ मुझे लगता है कि कुछ पूर्णांक पदोन्नति के लिए कुछ कर रहा है, लेकिन मुझे नहीं पता।
उदाहरण के लिए अहस्ताक्षरित चार का उपयोग :
unsigned charअक्सर कंप्यूटर ग्राफिक्स में उपयोग किया जाता है, जो अक्सर (हालांकि हमेशा नहीं) प्रत्येक रंग घटक को एक बाइट प्रदान करता है। आरजीबी (या आरजीबीए) रंग को 24 (या 32) बिट्स के रूप में दर्शाया जाना आम है, प्रत्येक unsigned char। चूंकि unsigned charमान [0,255] श्रेणी में आते हैं, आमतौर पर इनकी व्याख्या इस प्रकार की जाती है:
तो आप RGB लाल (255,0,0) -> (100% लाल, 0% हरा, 0% नीला) के साथ समाप्त होगा।
क्यों नहीं एक का उपयोग करें signed char? अंकगणित और बिट शिफ्टिंग समस्याग्रस्त हो जाती है। जैसा कि पहले से ही समझाया गया है, एक signed char'रेंज को अनिवार्य रूप से -128 द्वारा स्थानांतरित किया जाता है। RGB को ग्रेस्केल में परिवर्तित करने के लिए एक बहुत ही सरल और भोली (अधिकतर अप्रयुक्त) विधि सभी तीन रंग घटकों को औसत करने के लिए है, लेकिन यह समस्याओं में चलता है जब रंग घटकों के मान नकारात्मक होते हैं। unsigned charअंकगणित का उपयोग करते समय लाल (255, 0, 0) औसत (85, 85, 85) । हालाँकि, यदि मान signed char(127, -128, -128) थे, तो हम (-99, -99, -99) के साथ समाप्त हो जाएंगे, जो हमारे unsigned charअंतरिक्ष में (29, 29, 29) होगा , जो गलत है ।
यदि आप एक चरित्र को एक छोटे पूर्णांक के रूप में उपयोग करना चाहते हैं, तो ऐसा करने का सबसे सुरक्षित तरीका int8_tऔर uint8_tप्रकार है।
int8_tऔर uint8_tवैकल्पिक हैं और आर्किटेक्चर पर परिभाषित नहीं हैं जहां बाइट का आकार बिल्कुल 8 बिट्स नहीं है। इसके विपरीत, signed charऔर unsigned charहमेशा उपलब्ध हैं और कम से कम 8 बिट्स रखने की गारंटी है। यह एक सामान्य तरीका हो सकता है लेकिन सबसे सुरक्षित नहीं ।
signed charऔर unsigned char? या आप उस विशेष मामले में एक बेहतर "सुरक्षित" विकल्प सुझाएंगे? उदाहरण के लिए "वास्तविक" पूर्णांक प्रकारों के साथ छड़ी करने के लिए signed intऔर unsigned intकिसी कारण से?
signed charऔर unsigned charसभी अनुरूप कार्यान्वयन के लिए पोर्टेबल है और भंडारण स्थान को बचाएगा लेकिन कुछ छोटे आकार में वृद्धि हो सकती है। कुछ मामलों में, कोई बिटफ़िल्ड में छोटे मान या नियमित पूर्णांक प्रकार के एकल बिट्स को संग्रहीत करके अधिक संग्रहण स्थान बचाएगा। इस सवाल का कोई सटीक जवाब नहीं है, इस दृष्टिकोण की प्रासंगिकता हाथ में विशिष्ट मामले पर निर्भर करती है। और यह जवाब वैसे भी सवाल का जवाब नहीं देता है।
charऔर unsigned charसभी प्लेटफार्मों पर 8-बिट प्रकार होने की गारंटी नहीं दी जाती है - उन्हें 8-बिट या बड़ा होने की गारंटी दी जाती है। कुछ प्लेटफार्मों में 9-बिट, 32-बिट या 64-बिट बाइट्स हैं । हालांकि, आज (विंडोज, मैक, लिनक्स x86, आदि) सबसे आम प्लेटफार्मों में 8-बिट बाइट्स हैं।
signed charसीमा -128 से 127 है; unsigned char0 से 255 तक है।
char संकलक के आधार पर या तो हस्ताक्षरित चार या अहस्ताक्षरित चार के बराबर होगा, लेकिन एक अलग प्रकार है।
यदि आप सी-स्टाइल स्ट्रिंग्स का उपयोग कर रहे हैं, तो बस उपयोग करें char। यदि आपको अंकगणित (बहुत दुर्लभ) के लिए वर्णों का उपयोग करने की आवश्यकता है, तो पोर्टेबिलिटी के लिए हस्ताक्षरित या अहस्ताक्षरित निर्दिष्ट करें।
एक unsigned charअहस्ताक्षरित बाइट मान (0 से 255) है। आप char"चरित्र" होने के संदर्भ में सोच रहे होंगे लेकिन यह वास्तव में एक संख्यात्मक मूल्य है। नियमित रूप charसे हस्ताक्षरित है, इसलिए आपके पास 128 मान हैं, और ये मान ASCII एन्कोडिंग का उपयोग करते हुए पात्रों के लिए मैप करते हैं। लेकिन या तो मामले में, आप जो मेमोरी में स्टोर कर रहे हैं वह एक बाइट वैल्यू है।
प्रत्यक्ष मूल्यों के संदर्भ में एक नियमित चार का उपयोग तब किया जाता है जब मूल्यों को बीच में जाना जाता है CHAR_MINऔर CHAR_MAXजबकि एक अहस्ताक्षरित चार सकारात्मक छोर पर सीमा प्रदान करता है। उदाहरण के लिए, यदि CHAR_BIT8 है, तो नियमित की सीमा charकेवल [0, 127] होने की गारंटी है (क्योंकि इसे हस्ताक्षरित या अहस्ताक्षरित किया जा सकता है) जबकि unsigned char[0, 255] signed charहोगा और [-127, 127] होगा।
इसके लिए इसका उपयोग किए जाने के संदर्भ में, मानक POD (सादा पुराने डेटा) की वस्तुओं को सीधे अहस्ताक्षरित चार की एक सरणी में परिवर्तित करने की अनुमति देते हैं। यह आपको ऑब्जेक्ट के प्रतिनिधित्व और बिट पैटर्न की जांच करने की अनुमति देता है। सेफ़ या हस्ताक्षरित चार के लिए सुरक्षित प्रकार की समान गति की गारंटी मौजूद नहीं है।
unsigned char, विशेष रूप से एक सरणी के रूप में नहीं, और किसी भी "रूपांतरण" को केवल औपचारिक रूप से ऑब्जेक्ट से वास्तविक, घोषित सरणी में कॉपी करके और फिर बाद का निरीक्षण करके औपचारिक रूप से परिभाषित किया जाता है । यह स्पष्ट नहीं है कि OR को सीधे इस तरह के एक सरणी के रूप में पुन: व्याख्या किया जा सकता है, सूचक अंकगणित के लिए भत्ते के साथ यह प्रवेश करेगा, अर्थात इस उपयोग में "अनुक्रम" "सरणी" है या नहीं। यह स्पष्ट होने की उम्मीद में खोला गया एक कोर इश्यू # 1701 है। शुक्र है, क्योंकि यह अस्पष्टता मुझे हाल ही में परेशान कर रही है। unsigned char==
unsigned charOR के 1 में ले जा सकते हैं और फिर ++ptrवहां से आगे बढ़ते हुए इसके हर बाइट को पढ़ सकते हैं ... लेकिन AFAICT, इसे विशेष रूप से परिभाषित नहीं किया जा रहा है, इसलिए हम इसे स्वीकार कर रहे हैं यह अनुमान लगाने के लिए छोड़ दिया गया कि मानक में बहुत से अन्य मार्ग (और कई मायनों में, केवल अस्तित्व ) से 'शायद ठीक है'memcpy , एक पहेली के समान। जो आदर्श नहीं है। खैर, शायद शब्दांकन में सुधार होगा। यहाँ CWG समस्या है जिसका मैंने उल्लेख किया है लेकिन लिंक करने के लिए जगह की कमी है - open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1701
unsigned charसभी बिट चाल का दिल है। ऑल प्लेटफॉर्म के लिए लगभग सभी कंपाइलर में unsigned charएक बाइट और एक अनसाइन्टेड पूर्णांक (आमतौर पर) 8 बिट्स होते हैं जिन्हें छोटे पूर्णांक या बिट्स के पैक के रूप में माना जा सकता है।
नशे की लत में, जैसा कि किसी और ने कहा है, मानक एक चार के संकेत को परिभाषित नहीं करता है। तो आप 3 अलग है charप्रकार: char, signed char, unsigned char।
आप विशिष्ट लंबाई और signedness के विभिन्न प्रकार का उपयोग कर की तरह, तो आप शायद के साथ बेहतर बंद कर रहे हैं uint8_t, int8_t, uint16_t, आदि बस क्योंकि वे करते हैं कि वे क्या कहते हैं।
कुछ गुग्लिंग ने यह पाया , जहां लोगों ने इस बारे में चर्चा की थी।
एक अहस्ताक्षरित चार मूल रूप से एक एकल बाइट है। इसलिए, यदि आप डेटा के एक बाइट की आवश्यकता करते हैं, तो आप इसका उपयोग करेंगे (उदाहरण के लिए, शायद आप इसका उपयोग किसी फ़ंक्शन को पारित करने के लिए झंडे को सेट करने और बंद करने के लिए करना चाहते हैं, जैसा कि अक्सर विंडोज एपीआई में किया जाता है)।
एक अहस्ताक्षरित चार बिट का उपयोग करता है जो एक अन्य नंबर के रूप में एक नियमित चार के संकेत के लिए आरक्षित होता है। यह सीमा [[-128 - 127] के विपरीत [0 - 255] को बदल देता है।
जब आप कोई संकेत नहीं चाहते हैं तो आम तौर पर अहस्ताक्षरित चार्ट का उपयोग किया जाता है। बिट्स को शिफ्ट करने जैसे काम करने से कुछ फर्क पड़ेगा (शिफ्ट साइन को बढ़ाती है) और अन्य चीजें जब एक नंबर के रूप में उपयोग करने के बजाय एक बाइट के रूप में चार के साथ व्यवहार करती हैं।
"ग प्रोग्रामिंग लॉज" किताब से उद्धृत:
क्वालिफायर signedया unsignedचार या किसी पूर्णांक पर लागू किया जा सकता है। अहस्ताक्षरित संख्याएं हमेशा सकारात्मक या शून्य होती हैं, और अंकगणितीय मॉडुलो 2 ^ n के नियमों का पालन करती हैं, जहां n प्रकार में बिट्स की संख्या होती है। उदाहरण के लिए, यदि चार्ट 8 बिट्स हैं, तो अहस्ताक्षरित चार चर में 0 और 255 के बीच मान होते हैं, जबकि हस्ताक्षर किए गए चार्ट में -128 और 127 के बीच मान होते हैं (एक दो पूरक मशीन में।) चाहे सादे चार्ट पर हस्ताक्षर किए गए हों या अहस्ताक्षरित हो। -निर्भर, लेकिन मुद्रण योग्य वर्ण हमेशा सकारात्मक होते हैं।
signed charऔर unsigned charदोनों 1byte का प्रतिनिधित्व करते हैं, लेकिन उनके पास अलग-अलग रेंज हैं।
Type | range
-------------------------------
signed char | -128 to +127
unsigned char | 0 to 255
में signed charअगर हम विचार करें char letter = 'A', 'ए' में 65 की बाइनरी का प्रतिनिधित्व करते हैं ASCII/Unicode, तो 65 संग्रहित किया जा सकता, -65 भी संग्रहित किया जा सकता। ASCII/Unicodeनकारात्मक मूल्यों के बारे में चिंता करने की आवश्यकता के लिए कोई नकारात्मक द्विआधारी मूल्य नहीं हैं।
उदाहरण
#include <stdio.h>
int main()
{
signed char char1 = 255;
signed char char2 = -128;
unsigned char char3 = 255;
unsigned char char4 = -128;
printf("Signed char(255) : %d\n",char1);
printf("Unsigned char(255) : %d\n",char3);
printf("\nSigned char(-128) : %d\n",char2);
printf("Unsigned char(-128) : %d\n",char4);
return 0;
}
आउटपुट -:
Signed char(255) : -1
Unsigned char(255) : 255
Signed char(-128) : -128
Unsigned char(-128) : 128