2010-10-22 14 views
5
#include<stdio.h> 
int main(void) 
{ 
    char c = 0x80; 
    printf("%d\n", c << 1); 
    return 0; 
} 

उत्पादन इस मामले में -256 है। अगर मैं c << 0 लिखता हूं तो आउटपुट -128 है।यदि चार सी = 0x80, printf ("% d n", c << 1) output -256 क्यों करता है?

मैं इस कोड के पीछे तर्क समझ में नहीं आता।

+1

http://c-faq.com/ansi/maindecl.html –

+0

thnx fr correcting देखें। –

उत्तर

6

पहले से ही अपने प्रारंभिक बिंदु समस्याग्रस्त है:

char c = 0x80; 

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

फिर आप उस नकारात्मक मूल्य पर बाएं शिफ्ट कर रहे हैं। यह अपरिभाषित व्यवहार देता है।

  • की signedness char
  • कैसे signed char
  • char
  • संकेत प्रतिनिधित्व की चौड़ाई के 128 कन्वर्ट करने के लिए की पसंद: कुल में आप कई कार्यान्वयन परिभाषित विकल्प प्लस अपरिभाषित व्यवहार है कि परिणाम का निर्धारण किया है int (तीन संभावनाएं हैं)
  • नकारात्मकपर बाएं शिफ्ट को कार्यान्वित करने (या नहीं) पर विकल्प

इन सभी मामलों को देखने के लिए यह एक अच्छा अभ्यास हो सकता है कि विभिन्न परिणाम क्या हो सकते हैं।

सारांश में कुछ सिफारिशें:

  • सादा char
  • साथ एक चर अंकगणित
  • नहीं करते प्रारंभ करने के लिए एक उपयुक्त निरंतर चयन पर हस्ताक्षर किए प्रकार पर छोड़ दिया नहीं करते पारी
+0

आपके उत्तर के लिए धन्यवाद जेन्स सर। –

+0

स्पष्टीकरण का पहला अनुच्छेद गलत है और किसी को अनुभवहीन अनुभव कर सकता है। "चार सी = 0x80;" ठीक है जैसे "int c = 0xFFFFFFFF" ठीक है, लेकिन वह हिस्सा जो ठीक नहीं है, मान रहा है कि 0x80 128 होगा जब चार पर हस्ताक्षर किए जा सकते हैं (-128 से 127, 0 से 255 तक नहीं) –

+0

@ बी। नडोलसन , मुझे नहीं लगता कि यह भ्रामक है। निरंतर '0x80' प्रकार 'int' प्रकार है और इसका मूल्य' 128' है।आरएचएस पर इस प्रकार और मान को पहले निर्धारित किया जाता है, और उसके बाद उस प्रकार और मान को एलएचएस पर टाइप करने के लिए परिवर्तित किया जाता है। संभावित रूप से हस्ताक्षरित वैरिएबल को उस मान के साथ प्रारंभ करने का प्रयास करना जो प्रकार फिट नहीं है, एक अर्थपूर्ण त्रुटि है। –

18

char आपके प्लेटफ़ॉर्म पर हस्ताक्षर किए जा सकते हैं, इस मामले में 0x80 प्रतिनिधित्व करता है -128 (दो पूरक का मानना)।

जब एक char<< ऑपरेटर के साथ एक संकार्य के रूप में प्रयोग किया जाता है, यह int (अभी भी -128) करने के लिए प्रोत्साहित किया जाता है। तो जब आप बाएं-शिफ्ट को लागू करते हैं, तो आपको -256 मिलता है। तकनीकी रूप से, नकारात्मक मानों को स्थानांतरित करना कार्यान्वयन-परिभाषित अपरिभाषित है, लेकिन जो आप देखते हैं वह सामान्य व्यवहार है।

+0

मुझे नहीं लगता कि आपका कथन 'int' पदोन्नति के बारे में सही है। शिफ्ट ऑपरेटर पदोन्नति नहीं करते हैं, परिणाम प्रकार बाईं ओर प्रकार है। –

+0

@ जेन्स: निष्पक्ष होने के लिए, मेरे पास केवल मेरे सामने सी 99 मानक है। लेकिन यह धारा 6.5.7 में कहता है: "पूर्णांक प्रचार प्रत्येक ऑपरेंड पर किया जाता है।" –

+0

ओह, ठीक है। तो मैं इसे अपने उत्तर में भी एकीकृत कर दूंगा :) –

3

c0x80 असाइन किया गया है। 8-बिट बाइट मानते हुए, बाइनरी प्रतिनिधित्व में इसका मान 10000000 है। जाहिर है, आपके प्लेटफ़ॉर्म पर, char एक हस्ताक्षरित प्रकार है। तो, 0x80 (यानी 10000000) -128 के अनुरूप है।

<< एक char मूल्य को लागू किया जाता है, यह int के लिए प्रोत्साहित किया जाता है और संकेत संरक्षित है। इसलिए, 32-बिट पूर्णांक के साथ बाईं ओर एक बार स्थानांतरित होने पर, यह 11111111111111111111111100000000 (दो का पूरक) बन जाता है जो -256 है।

+0

'int' को पदोन्नति इस उदाहरण में 'printf' के साथ कुछ भी नहीं है; यह '<<' के कारण है। साथ ही, यह किसी के या दो पूरक में -256 का प्रतिनिधित्व नहीं है। –

+0

@ ओली सुधार के लिए धन्यवाद। –

+0

आपको बहुत धन्यवाद ओली और सीनान। मुझे तर्क समझा गया है .. –

0

मुझे आश्चर्य है कि क्यों अपने संकलक एक चेतावनी है कि 0x80 चार, जो अपने मंच पर 0x7F को -0x80 से केवल मूल्यों का प्रतिनिधित्व कर सकते हैं में फिट नहीं करता है के साथ शिकायत नहीं है।

#include <stdio.h> 
#include <limits.h> 
#include <stdlib.h> 

int main() { 
     printf("char can represent values from %d to %d.\n", CHAR_MIN, CHAR_MAX); 
     return EXIT_SUCCESS; 
} 

आपका स्थिति अतिप्रवाह कहा जाता है:

कोड के इस टुकड़े की कोशिश करो।

1

बस अतिरिक्त नोट के। नीचे के परिप्रेक्ष्य से, बिट-वार स्थानांतरण (और मास्किंग) एक आर्किटेक्चर की शब्द-लंबाई (बिट्स में व्यक्त) पर आधारित है। एक शब्द की लंबाई, आर्किटेक्चर से आर्किटेक्चर में भिन्न होती है।

See this Wiki page for word lengths by architecture

एक लक्ष्य वास्तुकला का शब्द लंबाई जानता है, एक गुणा करने के लिए थोड़ा बदलने, और भाग कर (कुछ मामलों में), तेजी से ऑपरेंड का उपयोग करने से उपयोग कर सकते हैं।

See this Wiki page for interesting diagrams of bit-shifting

के बाद से थोड़ा-स्थानांतरित कोड वास्तुकला निर्भर है, एक बिट स्थानांतरित कोड के किसी विशिष्ट अंश कल्पना नहीं कर सकते वास्तुकला के लिए वास्तुकला से उसी तरह काम करेंगे। हालांकि, एक बार विभिन्न आर्किटेक्चर के लिए अलग-अलग शब्द की लंबाई के विचार से परिचित होता है, बिट-स्थानांतरण कम रहस्यमय और अधिक अनुमानित हो जाता है।

शुक्र है, आज हम 8, 16, 32, और 64 बिट शब्द लंबाई, और विशेष रूप से 8 बिट चरित्र लंबाई है। प्राचीन कंप्यूटिंग के दिनों में, एक आर्किटेक्चर में 12, या 15, या 23 बिट शब्द की लंबाई हो सकती है (आदि, विज्ञापन मतली)।

+0

इस जानकारी को साझा करने के लिए धन्यवाद माइक सर। आप सभी को बहुत अच्छा ज्ञान है। –

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