2015-05-23 6 views
7

हम सभी जानते हैं कि कैसे सी में एक संरचना घोषित करने के लिए:संरचना घोषित करना: typedef struct name name;

struct Label1{ /* variables */ } Label2; // As I learned 

लेकिन मैं जानना चाहता है कि इस कोड 'struct नाम' घोषित करने के बिना काम करता हैं:

typedef struct name s_name; 

या वास्तव में, टाइपिंग करता है कोड

struct name; 

का मतलब है कि मैंने 'संरचना नाम' को शून्य संरचना के रूप में घोषित किया है या ऐसा कुछ? कोड की

उदहारण:

typedef struct Data Data; 
struct Data{ /*variables*/ }; 

प्रथम पंक्ति struct डाटा एक शून्य से एक के रूप में घोषित किया गया है में है, तो दूसरे में ऐसा लगता है कि मैं सदस्यों के साथ यह redeclaring कर रहा हूँ नहीं है।

इस बिंदु के लिए स्पष्टीकरण क्या है?

+2

सी संरचनाओं नाममात्र लिखे जाते हैं, एक अनुवाद इकाई के भीतर यानी प्रकार पहचान नाम से निर्धारित होता है; 'संरचना नाम' एक नया प्रकार घोषित करने के लिए पर्याप्त है, लेकिन जब तक एक और पूर्ण घोषणा (उर्फ परिभाषा) का सामना नहीं किया जाता है तब तक यह अधूरा अधूरा होगा; आप अधूरे प्रकार के साथ ऑब्जेक्ट्स के पॉइंटर्स प्राप्त कर सकते हैं, लेकिन स्पष्ट रूप से सदस्यों तक पहुंचने में सक्षम नहीं होंगे या चर घोषित करने के लिए इसका उपयोग नहीं करेंगे; एक अपूर्ण प्रकार की घोषणा को आगे की घोषणा के रूप में भी जाना जाता है; इसके उपयोगों में से एक अपारदर्शी पॉइंटर्स – Christoph

+1

@ माइकल हेडेलबर्ग "हम सभी जानते हैं कि सी में संरचना कैसे घोषित करें" - आपके प्रश्न के बाद मुझे यकीन नहीं है कि यह सच है। :) –

उत्तर

8

कुछ की तरह:

struct MyStruct; 

एक आगे संदर्भ बुलाया है। यह एक अधूरा प्रकार बनाता है और संकलक को बताता है कि उस नाम का एक प्रकार होगा (और यह एक संरचना है - यह यूनियनों के लिए भी इसी प्रकार काम करता है), और विवरण "बाद में अनुसरण करें"। इस प्रकार के प्रकार तक आप वैरिएबल को परिभाषित नहीं कर सकते, जब तक कि आप टाइप को पूरा न करें।

typedef struct MyStruct MyType; 

बस प्रकार नाम निर्धारित करेंगे कि struct किया जाना है। यह अभी भी एक अधूरा प्रकार है।

MyType *my_t_pointer; 
struct MyStruct *my_s_pointer; 

एक struct एक ही प्रकार की वस्तुओं की ओर इशारा करने के लिए के लिए जब आप पूर्ण घोषणा प्रदान यह उपयोगी है, "पूरा" के प्रकार:

हालांकि, अगर आप एक अधूरी प्रकार के लिए सूचक ले जा सकते हैं :

struct MyStruct { 
    struct MyStruct *next; 
}; 

वास्तव में इस एक ही रास्ता सूचियों, पेड़, और अन्य सभी पुनरावर्ती डेटा संरचनाओं के लिए नोड्स तैयार करना है। यह सी कार्यक्रमों (कभी-कभी छुपा) का एक प्रमुख हिस्सा है।

इसके अलावा, यह तंत्र कार्यान्वयन विवरण छुपाने के लिए उपयोग किया जाता है। शीर्षलेख में फ़ंक्शंस को केवल यह पता होना चाहिए कि संरचना पॉइंटर्स को ले जाने/पास करने के लिए मौजूद है। इन कार्यों के उपयोग को संरचना के विवरणों को जानने की आवश्यकता नहीं है (लेकिन इस तरह से इसे आवंटित नहीं किया जा सकता है, इसलिए मॉड्यूल को उन सभी पहलुओं को शामिल करना होगा जिन्हें संरचना पर विवरण जानने की आवश्यकता है)। पूर्ण घोषणा केवल मॉड्यूल की कार्यान्वयन फ़ाइल के अंदर है। इन पॉइंटर्स को "अपारदर्शी" कहा जाता है क्योंकि कोई "देखने" नहीं सकता है, यानी संरचना के क्षेत्र तक पहुंच सकते हैं क्योंकि वे इसे आसानी से नहीं जानते हैं।

my_module.h:

struct MyStruct; 

extern void my_init(struct MyStruct *obj); 

my_module.c:

struct MyStruct { 
    int f1; 
    ... 
}; 

my_init(struct MyStruct *obj) 
{ 
    ... 
} 
+0

मुझे मिल गया; इस स्पष्टीकरण के लिए धन्यवाद। –

2

typedef, struct नाम के लिए एक उपनाम के रूप में s_name वाणी ताकि आप चर घोषणा कर सकते हैं जैसे:

s_name *sptr; 

लाइन

struct name; 

वाणी वहाँ परिभाषित करने के बिना एक struct नाम कहा जाता है प्रकार है कि इसकी सामग्री आमतौर पर संरचना प्रकार में पॉइंटर्स के रूप में चर घोषित करने में सक्षम होने के लिए किया जाता है। जब तक इसे परिभाषित नहीं किया जाता है तब तक आप वास्तविक संरचना प्रकार के चर घोषित नहीं कर सकते हैं।

+1

मैं समझता हूं कि यहां दो नोटेशन हैं: घोषित करना संरचना; और इसकी सामग्री को परिभाषित करना? –

+0

Ususlly उन संयुक्त हैं लेकिन इसकी सामग्री को परिभाषित किए बिना एक संरचना प्रकार घोषित करना संभव है। यह एक अपूर्ण घोषणा है, क्रिस्टोफ द्वारा टिप्पणी भी देखें। –

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