अगर इस संरचना को किसी अन्य फ़ाइल func.c द्वारा उपयोग किया जाना है तो इसे कैसे करें?
जब किसी फ़ाइल (यानी func.c फ़ाइल) में एक प्रकार का उपयोग किया जाता है, तो इसे दिखाई देना चाहिए। यह करने के लिए सबसे खराब तरीका यह है कि प्रत्येक स्रोत फ़ाइल में इसे कॉपी पेस्ट करना चाहिए।
सही तरीके से इसे हेडर फ़ाइल में रखा जा रहा है, और जब भी ज़रूरत हो इस हेडर फ़ाइल को शामिल करें।
क्या हम एक नई हेडर फ़ाइल खोलेंगे और वहाँ संरचना की घोषणा करेंगे और उस हेडर को func.c में शामिल करेंगे?
यह वह समाधान है जो मुझे अधिक पसंद है, क्योंकि यह कोड को अत्यधिक मॉड्यूलर बनाता है। मैं आपकी संरचना को इस प्रकार कोडित करूंगा:
#ifndef SOME_HEADER_GUARD_WITH_UNIQUE_NAME
#define SOME_HEADER_GUARD_WITH_UNIQUE_NAME
struct a
{
int i;
struct b
{
int j;
}
};
#endif
मैं इस संरचना का उपयोग उसी हेडर (फ़ंक्शन जो "शब्दार्थ" इसके "इंटरफ़ेस" का हिस्सा हैं) में कर सकता हूं।
और आमतौर पर, मैं संरचना के नाम के बाद फाइल को नाम दे सकता हूं, और हेडर गार्ड को परिभाषित करने के लिए उस नाम का फिर से उपयोग कर सकता हूं।
यदि आपको संरचना के लिए एक सूचक का उपयोग करके एक फ़ंक्शन घोषित करने की आवश्यकता है, तो आपको पूर्ण संरचना परिभाषा की आवश्यकता नहीं होगी। एक सरल आगे की घोषणा की तरह:
struct a ;
पर्याप्त होगा, और यह युग्मन घटता है।
या हम हेडर फ़ाइल में कुल संरचना को परिभाषित कर सकते हैं और इसमें स्रोत और func.c दोनों को शामिल कर सकते हैं?
यह एक और तरीका है, कुछ हद तक आसान, लेकिन कम मॉड्यूलर: कुछ कोड को काम करने के लिए केवल आपकी संरचना की आवश्यकता होती है फिर भी सभी प्रकारों को शामिल करना होगा।
C ++ में, यह दिलचस्प जटिलता पैदा कर सकता है, लेकिन यह विषय से बाहर है (कोई C ++ टैग नहीं), इसलिए मैं विस्तृत नहीं करूंगा।
फिर दोनों फाइलों में उस संरचना को बाहरी घोषित कैसे करें। ?
मैं इस बिंदु को देखने में विफल रहता हूं, शायद, लेकिन ग्रेग हेवगिल ने अपनी पोस्ट में बहुत अच्छा उत्तर दिया है कि हेडर में एक संरचना कैसे घोषित की जाए जो कि सी में कई फ़ाइलों द्वारा उपयोग की जाए? ।
क्या हम इसे टाइप करेंगे, फिर कैसे?
- यदि आप C ++ का उपयोग कर रहे हैं, तो नहीं।
- यदि आप C का उपयोग कर रहे हैं, तो आपको करना चाहिए।
इसका कारण यह है कि C संरचना प्रबंधन एक दर्द हो सकता है: आपको हर जगह उपयोग किए जाने वाले संरचनात्मक कीवर्ड को घोषित करना होगा:
struct MyStruct ; /* Forward declaration */
struct MyStruct
{
/* etc. */
} ;
void doSomething(struct MyStruct * p) /* parameter */
{
struct MyStruct a ; /* variable */
/* etc */
}
जबकि एक टाइप्डिफ आपको बिना संरचना कीवर्ड के इसे लिखने में सक्षम करेगा।
struct MyStructTag ; /* Forward declaration */
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
void doSomething(MyStruct * p) /* parameter */
{
MyStruct a ; /* variable */
/* etc */
}
यह महत्वपूर्ण है कि आप अभी भी संरचना के लिए एक नाम रखें। लिख रहे हैं:
typedef struct
{
/* etc. */
} MyStruct ;
केवल एक टाइप-सी-एड नाम के साथ एक अनाम संरचना बनाएगा, और आप इसे अग्रेषित-घोषित करने में सक्षम नहीं होंगे। तो निम्न प्रारूप में रखें:
typedef struct MyStructTag
{
/* etc. */
} MyStruct ;
इस प्रकार, आप हर जगह MyStruct का उपयोग करने में सक्षम हो सकते हैं, जिसमें आप संरचनात्मक कीवर्ड जोड़ने से बचना चाहते हैं, और तब भी MyStructTag का उपयोग करें जब एक टाइपराइफ़ काम नहीं करेगा (अर्थात आगे की घोषणा)
संपादित करें:
सही ढंग से योनातान लेफ़लर द्वारा टिप्पणी के रूप में, C99 संरचना घोषणा के बारे में गलत धारणा ।
2018-06-01 संपादित करें:
क्रेग बार्न्स ने हमें अपनी टिप्पणी में याद दिलाया कि आपको संरचना "टैग" नाम और इसके "टाइप किए गए" नाम के लिए अलग-अलग नाम रखने की आवश्यकता नहीं है, जैसे मैंने स्पष्टता के लिए ऊपर किया था।
वास्तव में, उपरोक्त कोड को इस प्रकार लिखा जा सकता है:
typedef struct MyStruct
{
/* etc. */
} MyStruct ;
IIRC, यह वास्तव में वही है जो C ++ पर्दे के पीछे अपनी सरल संरचना की घोषणा के साथ करता है, इसे C के साथ संगत रखने के लिए:
// C++ explicit declaration by the user
struct MyStruct
{
/* etc. */
} ;
// C++ standard then implicitly adds the following line
typedef MyStruct MyStruct;
वापस C पर, मैंने दोनों usages (अलग-अलग नाम और एक ही नाम) देखे हैं, और किसी को भी मेरे बारे में कमियां नहीं हैं, इसलिए समान नाम का उपयोग करने से रीडिंग सरल हो जाती है यदि आप स्ट्रक्सेस और अन्य प्रतीकों के लिए C अलग "नेमस्पेस" का उपयोग नहीं करते हैं ।
struct b
, लेकिन तब आपकी संरचनाa
एक प्रकार की घोषणा करती है जो अप्रयुक्त है (आपको शायदk
आंतरिक नाम के ब्रेस के बाद एक सदस्य का नाम परिभाषित करना चाहिए। अर्धविराम से पहले।