2015-08-18 7 views
5

मैंने एक नई नौकरी के लिए के & आर के "सी प्रोग्रामिंग भाषा" के दूसरे संस्करण के भाषा संदर्भ (परिशिष्ट ए) के माध्यम से पढ़ना समाप्त कर दिया है।के एंड आर की सी पुस्तक के माध्यम से सी घोषणाओं को समझना, दूसरा संस्करण

कृपया ध्यान दें कि मैंने एसओ (इसलिए धन्यवाद;) पर सभी मार्गदर्शनों द्वारा सी घोषणाओं को पढ़ने के लिए कैसे काम किया है)। स्पष्टीकरण हमेशा सी
में अभिव्यक्तियों और ऑपरेटरों की प्राथमिकता का संदर्भ रहा है। मैं संदर्भ पुस्तिका ए.के.ए. परिशिष्ट ए, § ए 7 में एक ही प्राथमिकता तालिका का अनुमान लगा सकता हूं, कोई समस्या नहीं है।

हालांकि, § अभिव्यक्ति ऑपरेटरों की पूर्वता के साथ ए 7 सौदों, के रूप में खंड की शुरुआत में कहा जाता है - वर्ग कोष्ठक postfix-expression [ expression ] इस के साथ साथ सबस्क्रिप्ट ऑपरेटर के रूप में देखा जाता है, तारांकन * अविवेक ऑपरेटर के रूप में देखा जाता है और (argument-expression-list) कोष्ठकों है या () फ़ंक्शन कॉल से संबंधित हैं, § ए 7.3 देखें।
तो इतने सारे लोग इस प्राथमिकता तालिका का संदर्भ क्यों देते हैं, जब विषय सी घोषणाएं होती है, और यहां तक ​​कि SO पर कुछ अपवॉट प्राप्त होते हैं? परिभाषित करने का दावा करने वाली एकमात्र प्राथमिकता कुछ अभिव्यक्ति ऑपरेटरों की है।

कैसे घोषणाओं पार्स किया जा सकता § ए 8 में लिखा है कर रहे हैं, विशेष रूप से § A8.6 अधिक जटिल घोषणाओं की मूल बातें में चला जाता है।
लेकिन पूरे परिशिष्ट ए में, इस बात के बारे में कोई विवरण नहीं है कि वास्तव में कौन सी प्राथमिकताएं हैं, वास्तव में कोष्ठक, स्क्वायर ब्रैकेट, तारांकन, प्रकार के नाम और इतने पर पार्स किया जाना है।
पेज 216 पर यह कहता है कि ब्रांड्स जटिल घोषणाकर्ताओं के बाध्यकारी को बदल सकता है, लेकिन अब कैसे (हालांकि मेरे पास एक झटका है, मेरे उदाहरण में नीचे देखें)।

मैं आपको 'छद्म कोड' में एक उदाहरण देता हूँ जहाँ मैं बजे नुकसान में था, § A8.8 (प्रकार विनिर्देशक, D के declarators के लिए के लिए टी के रुख) का उपयोग:

पढ़ना एक सी घोषणा:

Original declaration: 
char (*(*f())[])() 

/* Have to use A8.6.3, because of how the decl. looks: */ 
Now let T=char , D=(*(*f())[])() 

D=D1(), where D1=(*(*f())[]) 
The type of f, according to A8.6.3 is then 
:L1 /* label 1 */ 
f is "type-modifiers of f in D1" function returning char /* note, in the book it says 'type-modifiers of f in T D1, but this wouldn't make any sense! */ 

    Now look at T D1 = char (*(*f())[]) 

    :ALT_A 
    The type of f in D1 = (*(*f())[]) is the same as that of f in 
    D2=*(*f())[] 
    /* At least, this is how parentheses are supposed to be understood, according to the beginning of A8.6, 
    where it says: 
     In a declaration T D where D has the form 
      (D1) 
    then the type of the identifier in the declaration D1 is the same as that of D. */ 
    /* note about that quote: the identifier in D has no type, did the authors mean to imply 'incomplete' types? 
    So, using incomplete types:*/ 
    Looking at D2 = T1 D3[] ----> have to use A8.6.2, where T1 = * , D3 = (*f()), 
    so the type of f in T1 D3 is 
    f is "type-modifiers of f in D3" array of pointers() 

     look at f in D3 = (*f()), or equivalently, f in D4 = *f(). Have to use A8.6.3. ---> 
     f is a function returning a pointer to() 

    going up a level: f is "type-modifiers of f in D3" array of pointers() 
    translates to: f is a function returning a pointer to an array of pointers() 

going up another level: f is "type-modifiers of f in D1" function returning char 
translates to: f is a function returning a pointer to an array of pointers to functions returning a char 

यह परिणाम है, cdecl भी पता चलता है। ध्यान दें कि मैंने किसी भी प्राथमिकता तालिका का उपयोग नहीं किया है, केवल संदर्भ मैनुअल और सीधे घोषणाओं से संबंधित अनुभाग।

तो इतने सारे लोग ऑपरेटर प्राथमिकता को कैसे और क्यों कहते हैं?
ऐसा लगता है कि ऑपरेटर प्राथमिकता के हर संदर्भ की तरह जब लोग सी घोषणाओं के बारे में पूछते हैं तो एक गलत जवाब है जो "पार्सिंग एल्गोरिदम" देता है जो सही परिणाम देने के लिए जादुई रूप से निकलता है।

और दूसरा, यह कैसे आता है कि & आर इतनी सारी चीजों के साथ इतना अचूक प्रतीत होता है (छद्म कोड में मेरी/* */- टिप्पणियां देखें)? मुझे और अधिक सटीकता की उम्मीद होगी, मेरा मतलब है कि वे स्पष्ट रूप से सभी विवरणों को जानते थे और उन्हें सटीक सोचने में सक्षम होना था।

गड़बड़ स्वरूपण के लिए खेद है, बीटीडब्ल्यू .. मैंने इस दिन का अधिकांश हिस्सा लिखने की कोशिश की है कि मैं इसे मैन्युअल रूप से कैसे पार्स करता हूं और साथ ही समझता हूं कि के & आर के साथ इसका अर्थ हो सकता है और यह फॉर्मूलेशन .. ।

स्रोतों, जहां घोषणाओं और ऑपरेटर पूर्वता जुड़ा होना कहा जाता है की सूची:

http://users.ece.utexas.edu/~ryerraballi/CPrimer/CDeclPrimer.html ("सभी एक तो किसी भी जटिल सी घोषणा समझने के लिए है, पता चला है कि इन घोषणाओं सी ऑपरेटर के आधार पर कर रहे हैं पूर्वता चार्ट, वही आप सी में भाव का मूल्यांकन करने का उपयोग करें: ")

http://binglongx.com/2009/01/25/how-to-read-a-cc-declaration/

How are (complex) declarations parsed in terms of precedence and associativity? (" वास्तव में, सी के डिजाइनरों के लिए पर्याप्त बुद्धिमान घोषणाओं ही उपयोग करने के लिए थे अभिव्यक्ति के रूप में "प्राथमिकता नियम"। यह "घोषणा का उपयोग करता है" नियम है। उदाहरण के लिए, अभिव्यक्ति "में, ब्रायन द्वारा पहले उत्तर देखें)

Operator precedence in C Definitions

विशेषज्ञ सी प्रोग्रामिंग:।।? डीप सी राज, पी 74, गूगल बुक्स पर 28 5 सितारा समीक्षा

+0

"हर कोई"? वह "हर कोई" कौन है? –

+0

मैंने उस प्रश्न को समायोजित किया, ऊपर देखें। धन्यवाद :) –

+1

यह बेहद अस्पष्ट है कि कैसे 'घोषणा' के पास 'ऑपरेटर प्राथमिकता' के साथ कुछ भी करना है। ये पूरी तरह से अलग और असंबंधित शब्द हैं। क्या आप वाकई सही शब्दावली का उपयोग कर रहे हैं? प्रश्न की शुरुआत में आपका बयान ** "मैंने सी घोषणाओं को पढ़ने के लिए कैसे काम किया है ... स्पष्टीकरण हमेशा सी में अभिव्यक्तियों और ऑपरेटरों की प्राथमिकता का संदर्भ रहा है" ** बहुत कम समझ में आता है !!! –

उत्तर

0

यह कारण है घोषणा को दर्शाता है उपयोग।

घोषणाओं के लिए व्याकरण में, एक declarator, एक सीधा-declarator के बाद एक सूचक भाग में विभाजित किया जाता है जिसमें सरणी बनाने [] और समारोह बनाने () निर्माणों पर लागू होती हैं, इसलिए किसी सरणी या समारोह के गठन एपी बनाने की तुलना में प्रकार की प्राथमिकता है ओइंटर प्रकार।

और, इस प्रतिबिंबित करते हैं, भाव के लिए व्याकरण में, पोस्टफ़िक्स ऑपरेटरों [] और () उपसर्ग एकल ऑपरेटर * की तुलना में अधिक पूर्वता है।

इसका मतलब यह है कि जब हम int *f() देख हम जानते हैं कि यह है कि इस int सूचक वाला फ़ंक्शन है, क्योंकि *f() प्रकार int के एक मूल्य देता है; इसी प्रकार हम जानते हैं कि char (*g)()char लौटने वाले फ़ंक्शन के लिए एक सूचक है, क्योंकि (*g)() को char प्रकार का मान देना चाहिए।

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

+0

अरे - मैं केवल लिखने के लिए बिक्री व्यवसाय में जाता हूं और यहां विज्ञापन करता हूं! फिर, आखिरकार लोगों को पता चलेगा कि "परिशिष्ट किसी को पढ़ने की उम्मीद नहीं है" कहां लिखना है। – BitTickler

+0

घोषणाओं के लिए व्याकरण में, एक घोषणाकर्ता को एक सूचक भाग में विभाजित किया जाता है जिसके बाद प्रत्यक्ष-घोषणाकर्ता होता है, जिसमें सरणी बनाने [] और फ़ंक्शन-फॉर्मिंग() संरचनाएं लागू होती हैं, इसलिए सरणी या फ़ंक्शन प्रकार बनाने से अधिक प्राथमिकता होती है एक सूचक प्रकार बनाने से पहले। एकमात्र बयान कहता है कि जिस क्रम में व्याकरण कहा गया है, वह परिभाषित करेगा कि § 7 में प्राथमिकता निर्धारित है ...

+0

@polynomial_donut जो पाठक को सिर्फ एक सहायता है; प्रत्येक व्याकरण में प्राथमिकता नियमों का एक संबद्ध सेट होता है, इसलिए यह बताने की कोई आवश्यकता नहीं है कि घोषणाओं के लिए व्याकरण इसकी प्राथमिकता का तात्पर्य है। – ecatmur

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