2012-11-09 23 views
6

में घोषणा नियम 'मैं सी प्रोग्रामिंग भाषा' पढ़ रहा हूं और संरचना के टाइपपीफ के बारे में एक समस्या का सामना करना पड़ा। कोड इस तरह है:स्ट्रक्चर टाइपपीफ

typedef struct tnode *Treeptr; 
typedef struct tnode { /* the tree node: */ 
    char *word; /* points to the text */ 
    int count; /* number of occurrences */ 
    struct tnode *left; /* left child */ 
    struct tnode *right; /* right child */ 
} Treenode; 

समय हम लिख

typedef struct tnode *Treeptr; 

tnode अभी भी अभी तक घोषित नहीं किया गया है, लेकिन हम किसी भी संकलन त्रुटि, नहीं मिलता है लेकिन जब हम बयान से ऊपर बदल में:

error: parse error before '*' token 
warning: data definition has no type or storage class 
:

typedef Treenode *Treeptr; 

हम संकलन त्रुटि मिलती है

क्या अंतर का कारण बनता है? "टर्नोड" के समान "संरचना tnode" नहीं है?

+0

आपको मिल सकता है [सी मानक का कौन सा हिस्सा इस कोड को संकलित करने की अनुमति देता है?] (Http://stackoverflow.com/questions/12200096/which-part-of-the-c- मानक-allows-this-code -टू-संकलन) और [क्या सी मानक मानता है कि इस शीर्षलेख में एक या दो 'संरचना अपरिवर्तनीय' प्रकार हैं?] (http://stackoverflow.com/questions/11697705/does-the-c- मानक- कॉन्सेडर - एक-या-दो-स्ट्रक्चर-अपरम्स-एंट्री-टाइप) प्रासंगिक के रूप में हैं, लेकिन उन्हें उस स्तर पर लगाया जा सकता है जहां आप हैं। –

उत्तर

6

आप इसे परिभाषित करने से पहले एक प्रकार का उपयोग नहीं कर सकते हैं।

typedef struct tnode { ... } Treenode; घोषणा के साथ, Treenode टाइप अर्ध-कॉलन तक पहुंचने तक परिभाषित नहीं किया गया है।

typedef struct tnode *Treeptr; के साथ स्थिति अलग है। यह संकलक को बताता है 'struct tnode नामक एक संरचना प्रकार है, और Treeptr टाइप struct tnode' के सूचक के लिए उपनाम है। उस घोषणा के अंत में, struct tnode एक अधूरा प्रकार है। आप अपूर्ण प्रकारों के लिए पॉइंटर्स बना सकते हैं लेकिन आप अधूरे प्रकार के चर नहीं बना सकते हैं (इसलिए आप Treeptr ptr1; या struct tnode *ptr2; परिभाषित कर सकते हैं और वे एक ही प्रकार के हैं, लेकिन आप struct tnode node; को परिभाषित नहीं कर सके)।

struct tnode के शरीर लिखा जा सकता है के रूप में: है

typedef struct tnode 
{ 
    char *word; 
    int  count; 
    Treeptr left; 
    Treeptr right; 
} Treenode; 

क्योंकि Treeptr संरचना से पहले प्रकार struct tnode * के लिए एक ज्ञात उर्फ ​​परिभाषित किया गया है। आप Treenode *left; का उपयोग नहीं कर सकते क्योंकि Treenode अंतिम अर्द्ध-कोलन तक पहुंचने तक ज्ञात उपनाम नहीं है (लगभग बोल रहा है)।

0

एक पंक्ति typedef struct tnode *Treeptr; ने "tnode" संरचना की आगे की घोषणा को निहित किया है। यह के समान है:

typedef struct tnode Treenode; 
typedef Treenode *Treeptr; 

struct tnode { /* the tree node: */ 
    char *word; /* points to the text */ 
    int count; /* number of occurrences */ 
    struct tnode *left; /* left child */ 
    struct tnode *right; /* right child */ 
}; 
1

जब आप TreePtr घोषित, आप struct को लागू नहीं कर रहे हैं। इसे "आगे घोषित" के रूप में जाना जाता है। कुछ ऐसा: "यहां हम इसका उपयोग करते हैं, लेकिन बाद में मैं इसे बेहतर समझाऊंगा"। कार्यान्वयन बाद में, केवल एक बार प्रकट होना चाहिए, और यह आपको दूसरे typedef में मिलता है।

और TreePtr संरचना के समान नहीं है, क्योंकि TreePtr वास्तव में एक नया प्रकार होगा जिसमें एक सूचक को मधुमक्खी का तथ्य शामिल है।

+0

धन्यवाद, फेलेक्स, अच्छा स्पष्टीकरण। तो आपका मतलब है कि 'स्ट्रक्चर undefined_struct * a;' की अनुमति है, लेकिन हमें 'undefined_struct'' को लागू करने से पहले 'struct undefined_struct b' लागू करना चाहिए, क्या यह सही है? लेकिन इस "_fardard declaration_" के लिए क्या इरादा है? – Rain

+1

अग्रेषित घोषणाएं, या अधूरे प्रकार, दो मामलों में सहायक हो सकते हैं। पारस्परिक रूप से रिकर्सिव संरचनाएं बनाना संभव है, ताकि 'संरचना ए' में 'संरचना बी' और 'स्ट्रक्चर बी' के लिए एक पॉइंटर होता है जिसमें 'स्ट्रक्चर ए' के ​​लिए एक पॉइंटर होता है। यह गूढ़ है (लेकिन अगली घोषणा संभव नहीं होने पर एक वास्तविक समस्या होगी)। अपूर्ण प्रकारों के लिए अधिक ठोस कारण यह है कि आप इंटरफ़ेस को अपूर्ण प्रकारों के लिए पॉइंटर्स के संदर्भ में फ़ंक्शंस के सेट में परिभाषित कर सकते हैं और सार्वजनिक हेडर को कभी भी नहीं करना चाहिए प्रकट करें कि संरचनाओं के अंदर क्या है; वे एक 'अपारदर्शी प्रकार' हैं, और आप जानकारी छिपाने का उपयोग कर रहे हैं। –

+0

आप किसी भी संयोजन में 'स्ट्रक्चर अंडिफ ए', 'स्ट्रक्चर अंडफ * बी;' इत्यादि जैसी चीजें कर सकते हैं, जितना आपको चाहिए उतना। आप शामिल कर सकते हैं ई उन्हें एक और संरचना के अंदर। लेकिन आप _must_ संरचना के कार्यान्वयन की घोषणा एक बार, कहां और कब पसंद करते हैं। –

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