Forskjellen mellom en struktur og en Union

stemmer
360

Er det noen gode eksempel for å gi forskjellen mellom en structog en union? Utgangspunktet jeg vet at structbruker alt minnet av dens medlems og unionbruker den største medlemmene plass i minnet. Er det noen andre OS nivåforskjell?

Publisert på 06/12/2008 klokken 17:56
kilden bruker
På andre språk...                            


15 svar

stemmer
599

Med en union, du bare skal bruke ett av elementene, fordi de er alle lagret på samme sted. Dette gjør det nyttig når du ønsker å lagre noe som kan være en av flere typer. En struct, på den annen side, har et eget lagersted for hver av sine elementer, og at de alle kan brukes på en gang.

For å gi et konkret eksempel på deres anvendelse, jeg var arbeider på en Scheme tolk en liten stund siden, og ble i det vesentlige ligger over de Scheme datatyper på de C-datatyper. Dette involverte lagring i en struct en enum som indikerer typen av verdi og en union for å lagre denne verdi.

union foo {
  int a;   // can't use both a and b at once
  char b;
} foo;

struct bar {
  int a;   // can use both a and b simultaneously
  char b;
} bar;

union foo x;
x.a = 3; // OK
x.b = 'c'; // NO! this affects the value of x.a!

struct bar y;
y.a = 3; // OK
y.b = 'c'; // OK

Edit: Hvis du lurer på hva innstillingen xb til 'c' endrer verdien av XA til, teknisk sett er det udefinert. På de fleste moderne maskiner en røye er en byte og en int er 4 byte, så gi XB verdien 'c' gir også den første byte av xa samme verdi:

union foo x;
x.a = 3;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);

utskrifter

99, 99

Hvorfor er de to verdiene det samme? Fordi de siste 3 byte av int 3 er alle null, så det er også leses som 99. Hvis vi satt i et større antall for XA, vil du se at dette er ikke alltid tilfelle:

union foo x;
x.a = 387439;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);

utskrifter

387427, 99

For å få en nærmere titt på den faktiske minneverdier, la oss sette og skrive ut verdiene i hex:

union foo x;
x.a = 0xDEADBEEF;
x.b = 0x22;
printf("%x, %x\n", x.a, x.b);

utskrifter

deadbe22, 22

Du kan tydelig se hvor 0x22 overskrev den 0xEF.

MEN

I C, er rekkefølgen av byte i en int ikke definert. Dette programmet overskrev den 0xEF med 0x22 på min Mac, men det er andre plattformer der det ville overskrive 0xDE i stedet fordi rekkefølgen av bytes som utgjør int ble reversert. Derfor, når du skriver et program, bør du aldri stole på oppførselen til skrive spesifikke data i en union, fordi det ikke er bærbar.

For mer lesing på bestilling av bytes, sjekk ut endianness .

Svarte 06/12/2008 kl. 17:59
kilden bruker

stemmer
76

Her er det korte svaret: en struct er en rekord struktur: hvert element i struct tildeler nye plassen. Så, en struct som

struct foobarbazquux_t {
    int foo;
    long bar;
    double baz; 
    long double quux;
}

allokerer i det minste (sizeof(int)+sizeof(long)+sizeof(double)+sizeof(long double))byte i minnet for hver forekomst. ( "Minst" fordi arkitektur innrettings begrensninger kan tvinge kompilatoren å puten struct).

På den andre siden,

union foobarbazquux_u {
    int foo;
    long bar;
    double baz; 
    long double quux;
}

tildeler en del av minnet og gir den fire aliaser. Så sizeof(union foobarbazquux_u) ≥ max((sizeof(int),sizeof(long),sizeof(double),sizeof(long double)), igjen med mulighet for noen tillegg for justeringer.

Svarte 06/12/2008 kl. 18:32
kilden bruker

stemmer
44

Er det noen gode eksempel for å gi forskjellen mellom en 'struct' og en 'fagforening'?

En tenkt kommunikasjonsprotokoll

struct packetheader {
   int sourceaddress;
   int destaddress;
   int messagetype;
   union request {
       char fourcc[4];
       int requestnumber;
   };
};

I denne imaginære protokollen, har det blitt sepecified at, basert på "meldingstype", vil følgende sted i overskriften enten være en forespørsel nummer, eller en fire tegnkode, men ikke begge deler. Kort sagt, fagforeninger tillate for samme lagringssted til å representere mer enn én datatype, hvor det er garantert at du bare vil ønske å lagre en av de typer data til enhver tid.

Fagforeninger er i stor grad et lavt nivå detalj basert på C kulturarv som et system programmeringsspråk, hvor "overlappende" lagringsplasser blir noen ganger brukt på denne måten. Du kan noen ganger bruke fagforeninger for å spare minne der du har en datastruktur der bare en av flere typer vil bli lagret på en gang.

Generelt, ikke OS ikke bryr seg eller vet om structs og fagforeninger - de er begge bare blokker av minne til den. En struct er en minneblokk som lagrer flere dataobjekter, hvor disse objekter ikke overlapper hverandre. En forening er en minneblokk som lagrer flere dataobjekter, men har bare lagring for den største av disse, og således kan bare lagre en av dataobjekter til enhver tid.

Svarte 08/12/2008 kl. 01:54
kilden bruker

stemmer
38

Som du allerede staten i spørsmålet ditt, den viktigste forskjellen mellom unionog structer at unionmedlemmene overlegg minnet om hverandre slik at sizeof av en fagforening er den ene, mens structmedlemmene er lagt ut en etter hverandre (med ekstra polstring i mellom). Også en union er stor nok til å romme alle medlemmene, og har en innretting som passer til alle sine medlemmer. Så la oss si intbare kan oppbevares ved 2 byte adresser og er 2 byte bred og lang kan bare lagres ved 4 byte adresser og er 4 byte. Følgende union

union test {
    int a;
    long b;
}; 

kunne ha en sizeofav fire, og en justering kravet om 4. Både en union og en struct kan ha polstring på slutten, men ikke i sin begynnelse. Skriving til en struct bare endrer verdien av medlem skrevet til. Skriving til et medlem av en fagforening vil gjengi verdien av alle andre medlemmer ugyldige. Du kan ikke få tilgang til dem hvis du ikke har skrevet til dem før, ellers atferden er udefinert. GCC gir som en forlengelse at du faktisk kan lese fra medlemmer av en fagforening, selv om du ikke har skrevet til dem sist. For en Operation System, det trenger ikke å spille noen rolle om en bruker programmet skriver til en forening eller en struktur. Dette er faktisk bare en sak av kompilatoren.

En annen viktig egenskap ved union og struct si, de tillater at en peker til dem kan vise til typer noen av sine medlemmer . Så følgende er gyldige:

struct test {
    int a;
    double b;
} * some_test_pointer;

some_test_pointer kan peke til int*eller bool*. Hvis du kaster en adresse av typen testtil int*, vil det peke på sitt første medlem, afaktisk. Det samme gjelder for en union også. Dermed fordi en union vil alltid ha rett justering, kan du bruke en union å gjøre å peke på noen type gyldig:

union a {
    int a;
    double b;
};

At foreningen vil faktisk være i stand til å peke til en int, og en dobbel:

union a * v = (union a*)some_int_pointer;
*some_int_pointer = 5;
v->a = 10;
return *some_int_pointer;    

er faktisk gyldig, som nevnt av C99 standard:

En gjenstand skal ha sin lagrede verdi nås bare med en l-verdi uttrykk som har en av de følgende typer:

  • en type som er kompatibel med den effektive type for objektet
  • ...
  • et aggregat eller union type som inneholder en av de ovennevnte typer blant medlemmene

Kompilatoren vil ikke optimalisere ut v->a = 10;som det kunne påvirke verdien av *some_int_pointer(og funksjonen vil gå tilbake 10i stedet for 5).

Svarte 06/12/2008 kl. 18:21
kilden bruker

stemmer
16

En unioner nyttig i et par scenarier. unionkan være et verktøy for svært lavt nivå manipulasjon som å skrive drivere for en kjerne.

Et eksempel på det er dissekere en floatrekke ved hjelp unionav en structmed bitfields og en float. Jeg sparer et nummer i float, og senere kan jeg få tilgang til bestemte deler av floatgjennom det struct. Eksempelet viser hvordan unionbrukes til å ha forskjellige vinkler for å se på data.

#include <stdio.h>                                                                                                                                       

union foo {
    struct float_guts {
        unsigned int fraction : 23;
        unsigned int exponent : 8;
        unsigned int sign     : 1;
    } fg;
    float f;
};

void print_float(float f) {
    union foo ff;
    ff.f = f;
    printf("%f: %d 0x%X 0x%X\n", f, ff.fg.sign, ff.fg.exponent, ff.fg.fraction);

}

int main(){
    print_float(0.15625);
    return 0;
}

Ta en titt på enkel presisjon beskrivelse på wikipedia. Jeg brukte eksemplet og det magiske tallet 0,15625 derfra.


unionkan også brukes til å implementere en algebraisk datatype som har flere alternativer. Jeg fant et eksempel på at i "Real World Haskell" bok av O'Sullivan, Stewart, og Goerzen. Sjekk det ut på The diskriminert union delen.

Jubel!

Svarte 06/09/2013 kl. 20:26
kilden bruker

stemmer
11

Ikke teknisk sett betyr:

Forutsetning: chair = minne blokk, folk = variabel

Struktur : Hvis det er 3 personer de kan sitte i stolen av sin størrelse tilsvarende.

Union : Hvis det er 3 personer bare en stol vil være der for å sitte, alle må bruke samme stol når de ønsker å sitte.

Teknisk sett betyr:

Nedenfor nevnte programmet gir et dypdykk inn i strukturen og union sammen.

struct MAIN_STRUCT
{
UINT64 bufferaddr;   
union {
    UINT32 data;
    struct INNER_STRUCT{
        UINT16 length;  
        UINT8 cso;  
        UINT8 cmd;  
           } flags;
     } data1;
};

Totalt MAIN_STRUCT size = sizeof (uint64) for bufferaddr + sizeof (UNIT32) for forening + 32 bit for polstring (avhengig av prosessorarkitektur) = 128 bit. For struktur alle medlemmene få minnet blokken contiguously.

Union får en minneblokk maks størrelse medlem (her sin 32 bit). Inne forening ett flere strukturen ligger (INNER_STRUCT) medlemmene få en hukommelseblokk av totale størrelse 32 bit (16 + 8 + 8). I forening enten INNER_STRUCT (32 bit) medlem eller data (32 bit) kan nås.

Svarte 16/12/2015 kl. 06:04
kilden bruker

stemmer
11

Ja, den største forskjellen mellom struct og union er samme som du sa. Struct bruker alt minnet av dens medlems og forening bruker den største medlemmene plass i minnet.

Men hele forskjellen ligger ved bruken behov for minnet. Beste bruk av unionen kan sees i prosessen med unix hvor vi gjør bruk av signaler. som en prosess kan virke på bare ett signal om gangen. Så den generelle erklæringen vil være:

union SIGSELECT
{
  SIGNAL_1 signal1;
  SIGNAL_2 signal2;
  .....
};

I dette tilfellet prosessen gjøre bruk av bare den høyeste minnet om alle signaler. men hvis du bruker struct i dette tilfellet, vil minnebruk være summen av alle signaler. Gjør mye forskjell.

For å oppsummere, Union bør velges hvis du vet at du får tilgang noen av medlem om gangen.

Svarte 03/01/2013 kl. 02:43
kilden bruker

stemmer
11

" Union " og " struct " er konstruksjoner av C-språk. Snakker av en "OS-nivå" Forskjellen mellom dem er upassende, siden det er den kompilatoren som produserer annen kode hvis du bruker ett eller annet søkeord.

Svarte 06/12/2008 kl. 18:06
kilden bruker

stemmer
9

Du har det, det er alt. Men så, i utgangspunktet, hva er poenget med fagforeninger?

Du kan sette på samme sted innhold av forskjellige typer. Du må vite hvilken type det du har lagret i union (så ofte du putter den i en structmed en type tag ...).

Hvorfor er dette viktig? Egentlig ikke for plass gevinster. Ja, du kan få noen biter eller gjøre noen padding men det er ikke hovedpoenget lenger.

Det er for type sikkerhet, det kan du gjøre noen form for 'dynamisk typing': kompilatoren vet at innholdet kan ha ulike betydninger og den presise betydningen av hvordan tolke det er opp til deg ved kjøring. Hvis du har en peker som kan peke på ulike typer, må du bruke en union, ellers kode kan være feil på grunn av aliasing problemer (kompilatoren sier til seg selv "oh, kan bare denne pekeren peker til denne typen, så jeg kan optimalisere ut disse tilganger ... ", og dårlige ting kan skje).

Svarte 06/12/2008 kl. 18:30
kilden bruker

stemmer
9

En struktur tildeler den totale størrelsen av alle elementer i den.

En union tildeler bare så mye minne som største medlem krever.

Svarte 06/12/2008 kl. 17:58
kilden bruker

stemmer
3

Bruken av fagforenings Fagforeninger brukes ofte når spesialisert type samtaler er nødvendig. For å få en idé om nytten av unionen. C / c standard bibliotek definerer ingen funksjon spesielt designet for å skrive korte heltall til en fil. Ved hjelp av fwrite () pådrar encurs stor administrasjon for enkel drift. Men ved hjelp av en fagforening kan du enkelt lage en funksjon som skriver binær av en kort heltall til en fil en byte om gangen. Jeg antar at korte heltall er 2 byte lang

EKSEMPELET:

#include<stdio.h>
union pw {
short int i;
char ch[2];
};
int putw(short int num, FILE *fp);
int main (void)
{
FILE *fp;
fp fopen("test.tmp", "wb ");
putw(1000, fp); /* write the value 1000 as an integer*/
fclose(fp);
return 0;
}
int putw(short int num, FILE *fp)
{
pw word;
word.i = num;
putc(word.c[0] , fp);
return putc(word.c[1] , fp);
}    

Selv om putw () i kalt med kort heltall, det var possble å bruke putc () og fwrite (). Men jeg ønsket å vise et eksempel for å dominstrate hvordan en union kan brukes

Svarte 13/07/2014 kl. 10:12
kilden bruker

stemmer
3

Strukturen er innsamling av annen datatype hvor forskjellige typer data kan ligge i det, og hver og en får sin egen blokk med minne

vi vanligvis brukes union når vi sikker på at bare én av variabelen vil bli brukt på en gang og du vil fullt utnyttelse av dagens minnet fordi det får bare en blokk med minne som er lik den største typen.

struct emp
{
    char x;//1 byte
    float y; //4 byte
} e;

minne totalt det bli => 5 byte

union emp
{
    char x;//1 byte
    float y; //4 byte
} e;

minne totalt det bli = 4 byte

Svarte 30/06/2014 kl. 09:27
kilden bruker

stemmer
2

hva er forskjellen mellom struktur og union?

Short cut Svaret er: Den ærbødighet er i minnetildeling. Forklaring: I struktur, vil minne bli opprettet for alle medlemmer innenfor strukturen. I union minne vil bli opprettet bare for et medlem som trenger største minneplass. Vurdere følgende kode:

struct s_tag
{
   int a; 
   long int b;
} x;

union u_tag
{
   int a; 
   long int b;
} y;

Her er det to medlemmer inne struct og union: int og lang int. Minneplass for int er: 4 byte og minneplass for lang int er: 8 i 32 bit-operativsystemet.

Så for struct 4 + 8 = 12 bytes vil bli opprettet mens 8 bytes vil bli opprettet for union

Kode eksempel:

#include<stdio.h>
struct s_tag
{
  int a;
  long int b;
} x;
union u_tag
{
     int a;
     long int b;
} y;
int main()
{
    printf("Memory allocation for structure = %d", sizeof(x));
    printf("\nMemory allocation for union = %d", sizeof(y));
    return 0;
}

Ref: http://www.codingpractise.com/home/c-programming/structure-and-union/

Svarte 04/01/2018 kl. 07:26
kilden bruker

stemmer
1

En Union er forskjellig fra et struct som en union gjentar over de andre: det omdefineres samme minne mens den struct danner den ene etter den annen uten overlappinger eller redefinisjonene.

Svarte 21/10/2017 kl. 11:51
kilden bruker

stemmer
1

Fagforeninger komme hendig mens du skriver en byte bestillingsfunksjon som er gitt nedenfor. Det er ikke mulig med structs.

int main(int argc, char **argv) {
    union {
        short   s;
        char    c[sizeof(short)];
    } un;

    un.s = 0x0102;

    if (sizeof(short) == 2) {
        if (un.c[0] == 1 && un.c[1] == 2)
            printf("big-endian\n");
        else if (un.c[0] == 2 && un.c[1] == 1)
            printf("little-endian\n");
        else
            printf("unknown\n");
    } else
        printf("sizeof(short) = %d\n", sizeof(short));

    exit(0);
}
// Program from Unix Network Programming Vol. 1 by Stevens.
Svarte 04/11/2013 kl. 19:41
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more