2013-07-03 8 views
11

सी में, तार चार (char *) के सरणी हैं और वर्ण आमतौर पर char में संग्रहीत होते हैं। मैंने देखा कि libC के कुछ फ़ंक्शन एक char के बजाय तर्क पूर्णांक के रूप में ले रहे हैं।क्यों पुचर, टॉपर, टोलर इत्यादि एक char के बजाय int int लेते हैं?

उदाहरण के लिए, चलिए toupper() और tolower() फ़ंक्शन लेते हैं जो दोनों int का उपयोग करते हैं। मैन पेज कहता है:

यदि सी एक हस्ताक्षरित चार मान या ईओएफ नहीं है, तो इन कार्यों का व्यवहार अपरिभाषित है।

मेरा अनुमान है कि एक int, toupper और tolowerunsigned char और EOF के साथ सौदा करने में सक्षम हैं के साथ। लेकिन वास्तव में EOF अभ्यास में है (क्या इसके मूल्य के बारे में कोई नियम है?) एक मान जिसे char के साथ संग्रहीत किया जा सकता है, और चूंकि वे फ़ंक्शन EOF को किसी और चीज़ में परिवर्तित नहीं करेंगे, मुझे आश्चर्य है कि toupper क्यों नहीं लेता तर्क के रूप में एक char।

किसी भी मामले में हमें ऐसा कुछ स्वीकार करने की आवश्यकता क्यों है जो एक चरित्र नहीं है (जैसे ईओएफ)? क्या कोई मुझे एक प्रासंगिक उपयोग केस प्रदान कर सकता है?

यह fputc या putchar साथ इसी तरह की है, वह भी एक int कि एक unsigned char में वैसे भी बदल जाती है ले लो।

मैं उस विकल्प के लिए सटीक प्रेरणा की तलाश में हूं। मैं आश्वस्त होना चाहता हूं, मैं जवाब नहीं देना चाहता कि मुझे नहीं पता कि कोई मुझे एक दिन पूछता है या नहीं।

+3

मैं किसी भी नियम है कि 'EOF' एक' char' में फिट करना चाहिए पता नहीं है, और मैं आपको विश्वास दिलाता कर सकते हैं कि 'char' जो' char' बजाय का उपयोग कर के बारे में अपने विचार-विमर्श करता है हस्ताक्षर किए जाने की गारंटी नहीं है, 'हस्ताक्षरित चार' का गलत लगता है। आप का मतलब है 'हस्ताक्षर चार' भर में। –

+0

क्या आपने इन कार्यों के कार्यान्वयन को देखा था। मुझे लगता है कि 'int' पैरामीटर ऑप्टिमाइज़ेशन उद्देश्यों के लिए है, क्योंकि इसके बाइट आकार प्रोसेसर रजिस्टरों के आकार के लिए उपयुक्त हैं। बदले में, एक बाइट 'char' चर को पर्दे के पीछे 'int' में परिवर्तित किया जाना चाहिए, और इस ऑपरेशन को संसाधित करने के लिए कुछ प्रोसेसर समय की आवश्यकता है। – sgnsajgon

+1

इसे पढ़ें: [ईओएफ की परिभाषा और इसका प्रभावी ढंग से उपयोग कैसे करें] (http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?id=1043284351&answer=1048865140) –

उत्तर

7

C11 7,4

हैडर <ctype.h> वर्गीकृत करने और मानचित्रण पात्रों के लिए उपयोगी कई कार्य की घोषणा की। सभी मामलों में तर्क एक int है, जिसका मान एक हस्ताक्षरित चार के रूप में प्रतिनिधित्व योग्य होगा या मैक्रो ईओएफ के मान के बराबर होगा। यदि तर्क का कोई अन्य मूल्य है, तो व्यवहार अपरिभाषित है।

C11 7.21.1

EOF

जो एक पूर्णांक निरंतर अभिव्यक्ति के लिए विस्तारित, प्रकार int और एक नकारात्मक मूल्य के साथ, ...

सी मानक स्पष्ट रूप से बताता है कि ईओएफ हमेशा ऋणात्मक मूल्य के साथ एक int है।और इसके अलावा, डिफ़ॉल्ट char प्रकार के signedness कार्यान्वयन परिभाषित किया गया है, तो यह अहस्ताक्षरित और एक नकारात्मक मूल्य स्टोर करने के लिए सक्षम नहीं हो सकता: यदि

C11 6.2.5

बुनियादी निष्पादन के एक सदस्य चरित्र सेट को char ऑब्जेक्ट में संग्रहीत किया जाता है, इसका मान गैर-ऋणात्मक होने की गारंटी है। यदि किसी अन्य वर्ण को चार ऑब्जेक्ट में संग्रहीत किया जाता है, तो परिणामी मान कार्यान्वयन-परिभाषित है लेकिन उस मान में प्रदर्शित किया जा सकता है कि मानों की सीमा के भीतर होगा।

+0

मेरा प्रश्न यह है कि: एक ऐसा फ़ंक्शन जो किसी पत्र को दूसरे में परिवर्तित करता है उसे कुछ ऐसा स्वीकार करना चाहिए जो पत्र नहीं है? (ईओएफ शामिल) –

1

यदि सी एक हस्ताक्षरित चार मान या ईओएफ नहीं है, तो इन कार्यों का व्यवहार अपरिभाषित है।

लेकिन EOF सी और कुछ प्लेटफॉर्म में एक नकारात्मक int है (हाय एआरएम!) charunsigned char के रूप में ही है।

+1

हां, लेकिन उन स्थानों पर जहां यह महत्वपूर्ण है , सी मानक कहते हैं "हस्ताक्षर किए गए चार या ईओएफ"। –

2

BITD एक कोडिंग विधि में शामिल हैं:

/* example */ 
int GetDecimal() { 
    int sum = 0; 
    int ch; 
    while (isdigit(ch = getchar())) { /* isdigit(EOF) return 0 */ 
    sum *= 10; 
    sum += ch - '0'; 
    } 
    ungetc(ch, stdin); /* If c is EOF, operation fails and the input stream is unchanged. */ 
    return sum; 
} 

तो isalpha(), tolower() जैसे विभिन्न कार्यों में इस्तेमाल किया जा सकता EOF के मूल्य के साथ ch

इस शैली ने putchar(EOF) के साथ समस्याएं पैदा कीं जो मुझे संदेह था कि putchar(255) जैसा ही था।

विधि विभिन्न कारणों से आज को हतोत्साहित किया गया है। निम्नलिखित जैसे विभिन्न मॉडल पसंद किए जाते हैं।

int GetDecimal() { 
    int ch; 
    while (((ch = getchar()) != EOF)) && isdigit(ch)) { 
    ... 
    } 
    ... 
} 
+0

मैंने उपयोग के उदाहरण के लिए आपका उत्तर +1 कर दिया है। लेकिन जैसा कि आपने कहा था, यह निराश हो गया है, इसलिए 'इदजिगिट' को कुछ ऐसा क्यों स्वीकार करना चाहिए जो चरित्र नहीं है? –

+0

@ मैक्सिम मुझे यकीन है कि यह ऐतिहासिक है कि 'isdigit()' '-1' स्वीकार करता है। संकल्पनात्मक रूप से, ईओएफ के बारे में सोचना मुश्किल नहीं है क्योंकि 'अन्य'। 'Isthis ...()' कार्यों को अक्सर 256 बाइट सरणी के साथ कार्यान्वित किया जाता है, जिससे 257 बाइट सरणी भी ईओएफ (-1) स्वीकार करने के लिए तुच्छ होती है। चूंकि यह आसान है और कड़े कोड के लिए बनाता है, जब तंग कोड उच्च मूल्य का था, तो यह एक अच्छा विस्तार था। अब, प्रत्येक बढ़ते मूल्य के कोड रखरखाव के साथ, इस मुहावरे ने पक्ष खो दिया है। – chux

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