2009-01-24 44 views
8

क्या कोई मुझे अनजान करने का उद्देश्य समझा सकता है? यह के & आर अध्याय 4 से है जहां आप एक रिवर्स पोलिश कैलक्यूलेटर बनाते हैं।ungetc (या के एंड आर से ungetch) का उद्देश्य क्या है?

मैंने बिना किसी त्रुटि के प्रोग्राम चलाया है और मेरे परीक्षणों में यह अभी भी वही काम करता है।

int getch(void) /* get a (possibly pushed back) character */ 
    { 
     if (bufp > 0) 
     { 
      return buf[--bufp]; 
     } 
     else 
     { 
      return getchar(); 
     } 
    } 

    void ungetch(int c) /* push character back on input */ 
    { 
     if (bufp >= BUFSIZE) 
     { 
      printf("ungetch: too many characters\n"); 
     } 
     else 
     { 
      buf[bufp++] = c; 
     } 

} 

(मैं यह स्पष्ट करने के getch में त्रिगुट ऑपरेटर हटा दिया है।)

उत्तर

26

मुझे उस विशिष्ट उदाहरण के बारे में पता नहीं है जिसका आप उल्लेख कर रहे हैं (यह प्रोबबी 23 साल है जब से मैं K& आर पढ़ता हूं, और यह पहला संस्करण था।), लेकिन अक्सर जब इसे 'peek' पर सुविधाजनक बनाना यह देखने के लिए अगला चरित्र है कि यह वर्तमान में पार्सिंग का हिस्सा है या नहीं। उदाहरण के लिए, यदि आप एक संख्या पढ़ रहे हैं तो आप अंकों को पढ़ना जारी रखना चाहते हैं जब तक कि आप एक गैर-अंक में न आएं। Ungetc संख्या पाठक को बिना किसी उपभोग के अगले चरित्र को देखने देता है ताकि कोई और इसे पढ़ सके। ग्रेग हेगिल के "2 3+" के उदाहरण में, संख्या पाठक 3 अंक पढ़ेगा, फिर प्लस साइन पढ़ें और पता होगा कि संख्या समाप्त हो गई है, फिर प्लस साइन को अनजेट करें ताकि इसे बाद में पढ़ा जा सके।

+0

बहुत बहुत धन्यवाद। अब यह बहुत अधिक समझ में आता है। – Tyler

+0

हालांकि यह केवल अर्थशास्त्र हो सकता है, लेकिन ungetc आपको इसे पढ़ने के बाद एक चरित्र को "धक्का" देने की अनुमति देता है ताकि इसे अगली पढ़ने वाली कॉल द्वारा फिर से पढ़ा जा सके। यह peeking के समान नहीं है, जो खपत के बिना पढ़ने का तात्पर्य है। –

+3

हां, peek getc के बराबर है ungetc के बाद। –

10

ऑपरेटरों के साथ स्पेस के बिना कार्यक्रम चलाने की कोशिश करें। मुझे उस उदाहरण के प्रारूप को ठीक से याद नहीं है और मेरे पास K & आर आसान नहीं है, लेकिन "2 3 +" "2 3+" का उपयोग करने के बजाय। ungetch() शायद संख्याओं को पार्स करते समय उपयोग किया जाता है, क्योंकि संख्या पार्सर अंकों को तब तक पढ़ेगा जब तक यह गैर-अंकीय न हो। यदि गैर-अंक एक स्थान है, तो अगला getch()+ पढ़ेगा और सब ठीक है। हालांकि, यदि अगला गैर-अंक + है, तो उसे उस इनपुट इनपुट पर वापस धक्का देना होगा ताकि मुख्य रीड लूप इसे फिर से ढूंढ सके।

आशा है कि मैं सही ढंग से उदाहरण याद कर रहा हूं।

+0

धन्यवाद है कि चाल करता है! – Tyler

+1

बढ़िया! चूंकि आप स्टैक ओवरफ़्लो के लिए नए हैं, इसलिए सबसे उपयोगी उत्तर पर "स्वीकार करें" (चेक मार्क पर क्लिक करें) को न भूलें। –

4

यह लेक्सिकल स्कैनर के लिए बहुत उपयोग किया जाता है (कंपाइलर का हिस्सा जो आपके टेक्स्ट को परिवर्तनीय नाम, स्थिरांक, ऑपरेटरों इत्यादि जैसे हिस्सों में तोड़ देता है)। फ़ंक्शन स्कैनर के लिए आवश्यक नहीं है, यह बहुत सुविधाजनक है।

जब आप एक परिवर्तनीय नाम पढ़ रहे हों, उदाहरण के लिए, आप तब तक नहीं जानते जब तक कि आप एक ऐसा वर्ण नहीं पढ़ते जब वे चर नाम का हिस्सा न हो। लेकिन फिर आपको उस चरित्र को याद रखना होगा और इसे लेक्सर के अगले हिस्से में संवाद करने का एक तरीका मिलना होगा। आप ग्लोबल वैरिएबल या कुछ बना सकते हैं, या इसे कॉलर को पास कर सकते हैं - लेकिन फिर आप अन्य चीजों को कैसे वापस करते हैं, जैसे त्रुटि कोड? इसके बजाए, आप इसे इनपुट स्ट्रीम में वापस रखने के लिए चरित्र को अनजान() करें, जो भी आपको अपने वैरिएबल नाम और वापसी के साथ करने की ज़रूरत है। फिर जब लेक्सर अगले खंड को पढ़ना शुरू कर देता है, तो उसे चारों ओर झूठ बोलने वाले अतिरिक्त पात्रों के लिए चारों ओर देखना नहीं पड़ता है।

+0

उत्तर के लिए धन्यवाद। उपयोग के वास्तविक जीवन उदाहरणों के लिए उपयोगी है। – Tyler

-2

इस कोड पर एक नजर डालें, तो आप समझ जाएंगे कि:

#include <conio.h> 
#include <stdio.h> 
int main() 
{ 
    int y=0; 
    char t[10]; 
    int u=0; 
    ungetch('a'); 
    t[y++]=getch(); 
    ungetch('m'); 
    t[y++]=getch(); 
    ungetch('a'); 
    t[y++]=getch(); 
    ungetch('z'); 
    t[y++]=getch(); 
    ungetch('z'); 
    t[y++]=getch(); 
    ungetch('a'); 
    t[y++]=getch(); 
    ungetch('l'); 
    t[y++]=getch(); 
    ungetch('\0'); 
    t[y++]=getch(); 
    ungetch('\0'); 
    t[y++]=getch(); 
    ungetch('\0'); 
    t[y++]=getch(); 
    printf("%s",t); 
    return 0; 
}