2011-01-20 23 views

उत्तर

11

आप संघ में किसी भी डेटा प्रकार का उपयोग कर सकते हैं, कोई प्रतिबंध नहीं है।

संरचनाओं पर यूनियनों के उपयोग के रूप में, संरचनाएं क्रमशः स्मृति में अपने डेटा को रखती हैं। इसका मतलब है कि उनके सभी उप-घटक अलग हैं।

यूनियन, दूसरी ओर, अपने सभी उप-घटकों के लिए समान स्मृति का उपयोग करते हैं, इसलिए केवल एक ही समय में मौजूद हो सकता है।

उदाहरण के लिए:

        +-----+-----+ 
struct { int a; float b } gives | a | b | 
           +-----+-----+ 
            ^ ^
            |  | 
       memory location: 150 154 
            | 
            V 
           +-----+ 
union { int a; float b } gives | a | 
           | b | 
           +-----+ 

संरचनाएं उपयोग किया जाता है, जहां एक "वस्तु" एक बिंदु दो पूर्णांकों, उन x और y जा रहा से मिलकर वस्तु की तरह, अन्य वस्तुओं से बना है निर्देशांक:

typedef struct { 
    int x;   // x and y are separate 
    int y; 
} tPoint; 

यूनियन आम तौर पर स्थिति में किया जाता है जहां एक वस्तु इस प्रकार कम भंडारण प्रणाली के रूप में कई चीजों में से एक है, लेकिन एक समय में केवल एक, हो सकता है:

typedef enum { STR, INT } tType; 
typedef struct { 
    tType typ;   // typ is separate. 
    union { 
     int ival;  // ival and sval occupy same memory. 
     char *sval; 
    } 
} tVal; 

वे पाते हैं कि हालांकि (एम्बेडेड सिस्टम की तरह के अलावा अन्य निम्न स्तर के काम में) कम और आजकल का कोई खास महत्व हो जाता है, तो आप इसे का एक बहुत नहीं दिख रहा है स्मृति को बचाने के लिए उपयोगी होते हैं।

+0

यूनियन स्मृति सहेजने के लिए नहीं हैं: वे एक * योग प्रकार *, यानी व्यक्त करते हैं। एक प्रकार जो धारण करता है। * या तो * एक फ्लोट * या * एक int। यूनियनों का उपयोग करना मुश्किल है, और काफी सीमित है। कृपया इसके बजाए 'boost :: variant' का उपयोग करने पर विचार करें। –

+11

मुझे डर है कि मुझे उस सब से बहुत असहमत होना है, @Alexandre :-) वे _are_ (अब भी) स्मृति को बचाने के लिए विशेष रूप से छोटे-एम्बेडेड दुनिया में उपयोगी हैं। यदि आप अंतर्निहित लेआउट (कार्यान्वयन-परिभाषित फॉइबल्स समेत) को समझते हैं और जब तक कोई पोर्ट सी को बढ़ावा देता है (टैग की जांच करें), तो वेरिएंट प्रकार का अधिक उपयोग नहीं किया जा रहा है :-) – paxdiablo

+0

मैं भूल गया 1) कि यह सी 2 था) कि लोगों को कभी-कभी हार्डवेयर के करीब होना चाहिए। फिर भी, मेरा मुद्दा यह है कि यूनियनों (सी ++ में) का उपयोग योग प्रकारों का प्रतिनिधित्व करने के लिए नहीं किया जाना चाहिए। –

4

खैर, आईएसओ/आईईसी 9899 के अनुसार: TC3 (C99 मानक):

एक संघ प्रकार सदस्य वस्तुओं का एक अतिव्यापी अरिक्त समुच्च्य का वर्णन करता है, जो एक वैकल्पिक निर्दिष्ट नाम और संभवतः अलग है में से प्रत्येक के प्रकार।

संक्षेप में, यूनियन के सदस्यों की स्मृति स्थान ओवरलैप करता है, और नाम आप यूनियन के सदस्यों को दे आप आकार में उस स्थान पर स्मृति को पढ़ने के लिए अनुमति देते हैं। विचार करें:

#include <stdio.h> 
#include <stdint.h> 

typedef union 
{ 
    struct 
    { 
     uint8_t a; 
     uint8_t b; 
     uint8_t c; 
     uint8_t d; 
    }; 
    uint32_t x; 
} somenewtype; 

typedef union 
{ 
    uint32_t* p; 
    uint8_t* q; 
} somepointer; 

int main(int argc, char** argv) 
{ 
    uint32_t r; 
    uint8_t s; 
    somenewtype z; 
    somepointer p; 
    r = 0x11223344; s = 0x11; 
    z.x = 0x11223344; 
    p.p = &r; 
    p.q = &s; 
    printf("%x%x%x%x\n", z.d, z.c, z.b, z.a); 
    printf("%x %x\n", *(p.p), *(p.q)); 
} 

पहले printf में, हम जो कर रहे हैं वह 32-बिट पूर्णांक के 8-बिट भागों को प्रिंट कर रहा है। उस अज्ञात संरचना में कोई पैडिंग के लिए पाठ्यक्रम की उम्मीद है।

दूसरे printf में? मैं gdb का उपयोग कर समझने के लिए से निकलने के लिए किया था, लेकिन मैंने किया था:

p.p = (uint32_t *) 0x7fffffffde5c; 
p.q = (uint8_t *) 0x7fffffffde5b "\021D3\"\021P\337\377\377\377\177"; 
p.p = (uint32_t *) 0x7fffffffde5b; 

निश्चित रूप से ठीक है, संकेत सभी एक ही आकार के होते हैं, इसलिए बताए p.qp.p का पता अधिलेखित कर देता है। मुझे दृढ़ता से संदेह है कि 8-बिट पॉइंटर के 32-बिट पूर्णांक के पते को संदर्भित करना "उस स्थान पर जो भी है + आकार में 32 बिट्स" प्रिंट कर रहा है जो मेरे लिए सह-संयोग से 22334411 होता है। लेकिन मुझे संदेह है कि उस समय, व्यवहार अपरिभाषित है।

  • यूनियनों एक अलग "प्रकार" संशोधक के माध्यम से एक ही स्मृति स्थान तक पहुँचने के लिए इस्तेमाल किया जा सकता:

    वैसे भी, कि छोटे से व्यायाम की बात आप पता चलता है कि था।

  • आपको सावधान रहना होगा कि आप क्या करते हैं और अंतर्निहित प्रकार को समझते हैं। यदि आप पॉइंटर्स का उपयोग करने जा रहे हैं, तो उनके संशोधन से सावधान रहें क्योंकि आप यह जानना शुरू कर सकते हैं कि कौन जानता है।

मैं कहना चाहिए मैं somepointer के लिए somenewtype लेकिन नहीं करने के लिए व्यावहारिक उपयोग देख सकते हैं - कि एक काल्पनिक उदाहरण मैं बहुत टूट जाएगा यकीन था।

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