2015-03-27 9 views
11

यदि मैं मानक इनपुट स्ट्रीम में "हैलो वर्ल्ड" शब्द टाइप करता हूं, तो यह प्रोग्राम अपेक्षित "हैलो वर्ल्ड" के बजाय मानक आउटपुट में अजीब बॉक्स प्रतीकों को प्रिंट करेगा।पुचर() अजीब आउटपुट, यह क्यों हो रहा है?

#include <stdio.h> 

int main(void) 
{ 
    // print out all characters from the stream until '/n' character is found 
    int ch; 
    while (ch = getchar() != '\n') 
    { 
     putchar(ch); 
    } 
    putchar('\n'); 
} 

मुझे समस्या को ठीक करने के बारे में पता है। लेकिन कोड की यह पंक्ति गलत क्यों है? जैसे != असाइनमेंट (=) की तुलना में अधिक पूर्वता है तुलना ऑपरेटरों -

while (ch = getchar() != '\n') 
+1

आप ऑपरेटर वैसे यहाँ precedences की एक सूची प्राप्त कर सकते हैं: //en.cp preference.com/w/c/language/operator_precedence। (थोड़ा सा मूर्खतापूर्ण जवाब मिला जो कि लाखों लोगों के साथ जवाब दे रहा था।: डी) – Ulfalizer

+0

दिलचस्प, मुझे नहीं लगता था कि सी में ऑपरेटर प्राथमिकता सी # और जावा से अलग होगी। – zxgear

+0

यदि आप इस विशेष मामले के बारे में सोच रहे हैं, तो यह जावा और सी # में समान लगता है। यह बुरा होगा यदि 'x_eq_y = x == y' को मूर्खतापूर्ण उदाहरण के रूप में '(x_eq_y = x) == y' के रूप में व्याख्या किया गया था। सी में कुछ भद्दा प्राथमिकताएं हैं (जिन्हें लेखकों द्वारा गलती के रूप में स्वीकार किया गया है, लेकिन अभी भी संगतता के लिए अन्य भाषाओं द्वारा अनुकरण किया गया है)। उदाहरण के लिए, 'x == y << z'' x == (y << z) 'जैसा ही आप अपेक्षा करते हैं, वही है, जबकि 'x == y और z'' (x = = वाई) और जेड'। – Ulfalizer

उत्तर

30

(ch = getchar() != '\n') क्योंकि !=C operator precedence table में तंग से = बांधता है के रूप में

((ch = getchar()) != '\n') 

फिर से लिखा जाना चाहिए। ऑपरेटर को बाएं से दाएं (अंग्रेजी की पढ़ने की दिशा) से आदेश नहीं दिया जाता है क्योंकि कोई उम्मीद कर सकता है। उदाहरण के लिए 2 + 3 * 5 का परिणाम 17 और 25 नहीं है। ऐसा इसलिए है क्योंकि *+ करने से पहले किया जाएगा, क्योंकि * ऑपरेटर + ऑपरेटर से अधिक प्राथमिकता है।

तो जब आप

ch = getchar() != '\n' 

की तरह कुछ लिखने आप इसे के बराबर होने की उम्मीद: (ch = getchar()) != '\n'

लेकिन असल में यह के बराबर है: ch = (getchar() != '\n')

का परिणाम क्योंकि != या तो true या false है, आप चरित्र 0 देखें स्क्रीन पर। मेरा मानना ​​है कि \001 आपके सिस्टम पर बॉक्स के रूप में दिखाई देता है।


1: चरित्र \001 या एक बॉक्स या डॉट या कुछ अजीब चरित्र के रूप में प्रकट हो सकता है यह उत्पादन में बिल्कुल भी दिखाई न दें।

+0

'उदाहरण के लिए 2 + 3 * 5 का परिणाम 17 है और 25 नहीं है .... यह एक अच्छा जवाब है, लेकिन यह '2 * 3 + 5' था, फिर भी इसका मूल्यांकन 11' 'और' 16' के रूप में नहीं .. इसे दाएं से बाएं मूल्यांकन के मुकाबले '' '' '' '' '' '' '' '' '' '' 'ऑपरेटर प्राथमिकता के साथ करना है। कुछ रूकी इसे गलत तरीके से ले लेंगे। \ – WedaPashi

+0

@WedaPashi आपकी सहायक टिप्पणी के लिए धन्यवाद, मैं तदनुसार अपना उत्तर अपडेट करूंगा। –

+1

प्रोग्राम तर्क से, \ 000 "कभी नहीं" देखा जाएगा, न कि "शायद ही कभी"। जैसे ही गेटकार() रिटर्न '\ n', ch को 0 असाइन किया जाता है और लोब बॉडी निष्पादित नहीं होती है। –

9

आप operator precedence के बारे में पता होना चाहिए। आवश्यक व्यवहार लागू करने के लिए कोष्ठकों का प्रयोग करें, यानी परिवर्तन:

while (ch = getchar() != '\n') 

रहे हैं:

while ((ch = getchar()) != '\n') 


परिशिष्ट: नीचे एक अलग जवाब में @TomGoodfellow से सलाह के ध्यान रखना सुनिश्चित करें - एक का उपयोग कर चेतावनियों के साथ सभ्य संकलक सक्षम (उदाहरण के लिए gcc -Wall) आपको तुरंत इस समस्या के बारे में सूचित करेगा।

5

क्योंकि आप के रूप में while ((ch = getchar()) != '\n')

+1

जबकि आप बहुत सही हैं, आपको कुछ विवरण जोड़ना चाहिए कि इसके जवाब में, कैसे और क्यों इसे एक महान बनाने के लिए। चीयर्स !! :-) –

12

और एक से थोड़ा मेटा-ish जवाब है, व्यापक ठीक हमेशा चेतावनी को सक्षम करने पर संकलन के रूप में यह लिखने के लिए की जरूरत है:

$ gcc t.c -Wall 
t.c: In function ‘main’: 
t.c:7:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses] 
    while (ch = getchar() != '\n') 
    ^
t.c:12:1: warning: control reaches end of non-void function [-Wreturn-type] 
} 
^ 

या बेहतर अभी तक बजना कोशिश है, जो डिफ़ॉल्ट रूप से चेतावनी देते हैं और आम तौर पर बेहतर नैदानिक ​​संदेश देता है:

$ clang t.c 
t.c:7:15: warning: using the result of an assignment as a condition without parentheses [-Wparentheses] 
    while (ch = getchar() != '\n') 
      ~~~^~~~~~~~~~~~~~~~~~~ 
t.c:7:15: note: place parentheses around the assignment to silence this warning 
    while (ch = getchar() != '\n') 
     ^
      (     ) 
t.c:7:15: note: use '==' to turn this assignment into an equality comparison 
    while (ch = getchar() != '\n') 
      ^
       == 
1 warning generated. 
संबंधित मुद्दे