2011-01-20 31 views

cevap

11

Sendikadaki herhangi bir veri türünü kullanabilirsiniz, kısıtlama yoktur. Yapılar üzerinde sendikaların kullanımı ile ilgili olarak, yapılar belleğinde sıralı olarak kendi verilerini ortaya koymaktadır. Bu, tüm alt bileşenlerinin ayrı olduğu anlamına gelir. Diğer taraftan, birleşikler, tüm alt bileşenleri için aynı belleği kullanırlar, böylece aynı anda yalnızca bir tane var olabilir. Örneğin

:

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

Yapılar kullanılan bir "nesne" iki tam sayı, o, x ve y toplamı oluşan bir nokta nesne gibi, diğer nesnelerin oluşmaktadır koordinatları:

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; 
: bir amacı, böyle bir tip daha az depolama sistemi olarak birçok şeyler aynı aynı anda yalnızca biri olabilir burada

Birlikler tipik durumda kullanılan

Bellek tasarrufu için kullanışlıdırlar, ancak bu günlerde daha az ve daha az endişe duyma eğilimindedir (gömülü sistemler gibi düşük seviyeli çalışmalardan başka), böylece çok fazla görmüyorsunuz.

+0

Sendikalar hafızayı kaydetmek için değil: * toplamı *, yani ifade ederler. ör. * ya * bir float * veya * int. Sendikalar kullanımı zor ve oldukça sınırlı. Lütfen bunun yerine 'boost :: variant' kullanmayı düşünün. –

+11

Korkarım ki hemen hemen hepsine katılmam gerekiyor, @Alexandre :-) Onlar, özellikle küçük gömülü dünyada hafıza kaydetmek için yararlı olan _are_ (şimdi bile). Altta yatan düzeni (uygulama tanımlı foible'lar dahil) ve birisinin portları C'ye (etiketleri kontrol et) kadar artırırsanız kullanması zor değildir, varyant türü çok fazla kullanılmayacaktır :-) – paxdiablo

+0

Unuttuğum 1) C 2) insanların bazen donanıma yakın olması gerektiği. Yine de, benim amacım, (C++) sendikaların toplamı temsil etmek için kullanılmamasıdır. –

4

O ISO/IEC 9899 'e göre TC 3 (C99 standardı):

bir birlik tipi eleman nesnelerin üst üste binen bir dizi boş olmayan tarif, isteğe bağlı olarak, belirtilen adı ve muhtemelen farklı olan her yazın. Kısacası

, sendika üyelerinin bellek alanı örtüşür ve sendika üyelerine vermek adları boyutu söz konusu konumda hafızayı okumak için izin verir. Düşünün:

#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)); 
} 

ilk printf olarak, yaptığımız şey, 32-bit tamsayı 8 bitlik parçalar yazdırmak olduğunu. Bu anonim yapıda hiçbir dolgu için ders umuyoruz.

İkinci baskısında? Anlamaya gdb kullanarak yoluyla adım vardı ama yaptım: tabii

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

Eh, işaretçileri böylece p.qp.p adresini üzerine yazar atama hepsi aynı boyda. 32 bitlik tamsayı adresinin 8 bitlik bir işaretçiye atıfta bulunulmasının, "bu konumda ne olursa olsun + 32 bit boyutunda" yazdırması, benim için tesadüf eseri 22334411 olur. Ama şüpheliyim ki, bu noktada davranış tanımsızdır.

  • sendikalar farklı bir "tip" değiştirici aracılığıyla aynı bellek konumuna erişmek kullanılabilir:

    neyse, o küçük egzersiz noktası olduğunu göstermekti.

  • Ne yaptığınıza ve kullandığınız temel türü anladığına dikkat etmelisiniz. Eğer imleci kullanacaksanız, kim olduğunu bilerek işaret etmeye başlayacağınız için değişikliklerine dikkat edin.

ben somepointer için somenewtype ancak pratik kullanım görebilirsiniz işaret olmalıdır - yani ben kıracak emindim örnekleyen bir örnek oldu.

İlgili konular