2012-11-14 13 views
8

मैं ISO C11 द्वारा अनुमति के रूप में एक कोड समान डेमो नीचे दिखाया गया के रूप में लागू ..सी में अज्ञात structs/संघों के क्या फायदे हैं?

struct st 
{ 
int a; 
struct 
{ 
int b; 
}; 
}; 

6,58 अनाम struct/union भीतर structs/unions

क्षेत्रों पाया।

लेकिन इसके क्या फायदे हैं?

क्योंकि वैसे भी मैं की तरह

int main() 
{ 
struct st s; 
s.a=11; 
s.b=22; 
return 0; 
} 

साथ जीसीसी 4.5.2 पर संकलित एक ही तरीके से डेटा सदस्यों तक पहुँच सकते हैं,

gcc -Wall demo.c -o demo 

और कोई त्रुटि,

+0

संभावित डुप्लिकेट [अज्ञात structs और यूनियन सी 11 में उपयोगी क्या हैं?] (Http://stackoverflow.com/questions/8932707/what-are-anonymous-structs-and-unions-useful-for-in- सी 11) –

उत्तर

14

यह एक संरचना के अंदर एक अज्ञात संरचना नहीं है, जो मुझे बहुत उपयोगी नहीं लगता है: यह आमतौर पर अधिक पैडिंग शुरू करके थोड़ा लेआउट बदल देगा, अन्य दृश्य प्रभावों के साथ (सदस्यों के इनलाइन करने की तुलना में) मूल संरचना में बाल संरचना)।

मुझे लगता है कि अज्ञात संरचना/यूनियनों का लाभ कहीं और है: इन्हें किसी इकाई के अंदर एक अज्ञात संरचना या किसी संरचना के अंदर अज्ञात संघ रखने के लिए उपयोग किया जा सकता है।

उदाहरण:

union u 
{ 
    int i; 
    struct { char b1; char b2; char b3; char b4; }; 
}; 
+1

क्या आप इस यूनियन का उपयोग कैसे कर सकते हैं? उदाहरण के लिए, यदि मेरे पास आपके उदाहरण का एक्स है और 'x.b1 =' a'' 'का उपयोग करें, तो शेष बी 2, बी 3, बी 4 प्रारंभ हो जाएंगे और मेमोरी स्पेस लेंगे? – Herbert

+0

@ हर्बर्ट एक संघ के अंदर पारंपरिक (नामित) संरचना के समान है। आपका प्रश्न वास्तव में structs युक्त संघों के बारे में है। आपको इसे एक अधिक विशिष्ट प्रश्न के उत्तर पर टिप्पणी के बजाय एक SO प्रश्न के रूप में पूछना चाहिए, लेकिन चूंकि आपने बाद में किया था, 'x.b1 =' a'' सदस्यों को 'b2',' b3' प्रारंभ नहीं करता है , 'बी 4' लेकिन ये "मेमोरी स्पेस लेते हैं", जैसा कि' sizeof (union u) 'के मूल्य को प्रिंट करके देखा जा सकता है। सिद्धांत रूप में, यदि आप 'यूनियन यू' वैरिएबल घोषित करते हैं जिसमें से आप कभी भी 'बी 1' सदस्य का उपयोग करते हैं, तो पर्याप्त स्मार्ट कंपाइलर केवल 'बी 1' के लिए स्मृति आरक्षित कर सकता है, ... –

+0

@ हर्बर्ट लेकिन सिद्धांत रूप में' यूनियन यू ' ऑब्जेक्ट का अर्थ है कि आप बाद में मौजूद structs के किसी भी सदस्य को लिखना चाह सकते हैं, इसलिए स्मृति उनके लिए आरक्षित होनी चाहिए। –

11

लाभ है बहुत स्पष्ट है, है ना? यह प्रोग्रामर को नाम से आने से बचाता है! naming things is hard के बाद से, यह अच्छा है कि यदि वास्तविक आवश्यकता नहीं है तो ऐसा करने से बचना संभव है।

यह भी एक बहुत स्पष्ट संकेत है कि इस struct स्थानीय है और कभी नहीं कहीं और थे, लेकिन, माता पिता struct, जो वास्तव में है के एक खेत जा रहा है वास्तव में अच्छा सूचना के संदर्भ में, क्योंकि यह अनावश्यक युग्मन के संभावना कम कर देता है ।

इसे static के रूप में सोचें; यह आंतरिक struct की बाहरी दृश्यता की दृष्टि को प्रतिबंधित करता है, जैसा कि static वैश्विक प्रतीकों की दृश्यता को संकलित इकाई में दिखाता है, जैसा कि वे दिखाई देते हैं।

+0

थोड़ा विस्तृत .. स्थिर ?? और एक और यदि वह अंदर स्थानीय है तो पहचानकर्ता के समान नाम का उपयोग करने से त्रुटि मिलती है .. लेकिन फ़ंक्शन में हम ब्लॉक स्कोप के कारण {} के अंदर समान नाम पहचानकर्ता दे सकते हैं क्यों इसे यहां स्ट्रक्चर की अनुमति नहीं है {} – Omkant

+4

'struct' इतना स्थानीय हो जाता है कि यह समझना मुश्किल है कि क्यों प्रोग्रामर अपने सदस्यों को सीधे मूल संरचना में रेखांकित नहीं कर रहा है। अपने वर्तमान संस्करण में यह उत्तर उस विकल्प के संबंध में किसी भी लाभ की सूची नहीं देता है। इनलाइन सदस्यों की तुलना में लेआउट नेस्टेड स्ट्रक्चर के बीच अलग है (अधिक पैडिंग के साथ, जो इच्छित प्रभाव हो सकता है लेकिन आमतौर पर एक नुकसान माना जाएगा)। –

+0

ऐसा लगता है कि उपरोक्त कारण के लिए अज्ञात 'संघ' अज्ञात संरचना से कहीं अधिक फायदेमंद है। – sherrellbc

1

मैं सिर्फ गुमनाम union की एक बड़ी लाभ में फंस गयी। हालांकि चेतावनी दी जानी चाहिए कि यह बेहोश दिल की कहानी नहीं है और न ही यह एक अनुशंसित अभ्यास है।

स्रोत कोड के सैकड़ों के एक पुराने सी कार्यक्रम में फ़ाइलों को वहाँ एक वैश्विक चर, एक struct है, जो एक सदस्य के रूप में एक struct निहित है।

typedef struct { 
    LONG  lAmount; 
    STRUCTONE largeStruct; // memory area actually used for several different struct objects 
    ULONG  ulFlags; 
} STRUCTCOMMON; 

struct, STRUCTONE, कई बड़े structs में से एक है लेकिन दूसरों थे हर समय इस कोड को लिखा गया था पर STRUCTONE से छोटी थी: तो वैश्विक चर के लिए प्रकार परिभाषा जैसे कुछ बात देखा। तो इस स्मृति क्षेत्र, largeStruct को union के रूप में उपयोग किया जा रहा था, लेकिन उचित स्रोत बयान के बिना ऐसा संकेत मिलता है। memcpy() का उपयोग करके इस क्षेत्र में विभिन्न struct चर की प्रतिलिपि बनाई गई थी।कभी-कभी मामलों को और भी खराब बनाने के लिए यह वैश्विक चर के वास्तविक नाम और कभी-कभी वैश्विक चर के सूचक के माध्यम से होता था।

आमतौर पर ऐसा होता है जैसे हालिया परिवर्तनों में प्रगति होती है जिसके परिणामस्वरूप अन्य structs सबसे बड़े होते हैं। और मुझे एक सौ फाइलों से गुज़रने का सामना करना पड़ा जहां यह सभी विभिन्न उपनामों और अन्य सभी चीज़ों के साथ उपयोग किया जा रहा था।

और फिर मुझे अज्ञात यूनियन याद आया। इसलिए मैं typedef संशोधित निम्नलिखित हो:

typedef struct { 
    LONG  lAmount; 
    union { 
     // anonymous union to allow for allocation of largest space needed 
     STRUCTONE largeStruct; // memory area actually used for several different struct objects 
     STRUCTTHREE largerStruct; // memory area for even larger struct 
    }; 
    ULONG  ulFlags; 
} STRUCTCOMMON; 

और फिर हर चीज कंपाइल।

तो अब स्रोत कोड समीक्षा और प्रतिगमन परीक्षण के उन सभी दिनों में मैं दुखी था कि अब और आवश्यक नहीं है।

और अब मैं इस स्रोत का उपयोग करके धीरे-धीरे स्रोत को संशोधित करने की प्रक्रिया शुरू कर सकता हूं ताकि इस स्रोत को अपने समय सारणी पर अधिक आधुनिक मानकों तक पहुंचाया जा सके।

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