Verschil tussen een structuur en een unie

Is er een goed voorbeeld om het verschil te geven tussen een structen een union?
In principe weet ik dat structal het geheugen van zijn lid gebruikt en unionde grootste geheugenruimte van leden gebruikt. Is er een ander OS-niveauverschil?


Antwoord 1, autoriteit 100%

Bij een union mag je maar één van de elementen gebruiken, omdat ze allemaal op dezelfde plek zijn opgeslagen. Dit maakt het handig wanneer u iets wilt opslaan dat van verschillende typen kan zijn. Een struct daarentegen heeft een aparte geheugenlocatie voor elk van zijn elementen en ze kunnen allemaal tegelijk worden gebruikt.

Om een concreet voorbeeld van het gebruik ervan te geven, werkte ik een tijdje geleden aan een Schema-interpreter en legde ik in wezen de Schema-gegevenstypen over de C-gegevenstypen heen. Dit omvatte het opslaan in een structeur van een opsomming die het type waarde aangeeft en een unie om die waarde op te slaan.

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:Als je je afvraagt met welke instelling x.b in ‘c’ de waarde van x.a verandert, technisch gezien is deze niet gedefinieerd. Op de meeste moderne machines is een char 1 byte en een int is 4 bytes, dus als x.b de waarde ‘c’ geeft, krijgt de eerste byte van x.a dezelfde waarde:

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

afdrukken

99, 99

Waarom zijn de twee waarden hetzelfde? Omdat de laatste 3 bytes van de int3 allemaal nul zijn, dus het wordt ook gelezen als 99. Als we in een groter aantal voor x.a plaatsen, zie je dat dit niet altijd het geval is:

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

PRINTS

387427, 99

Let de waarden in HEX in om een ​​kijkje te krijgen van de werkelijke geheugenwaarden. Laten we de waarden in HEX afdrukken:

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

PRINTS

deadbe22, 22

U kunt duidelijk zien waar de 0x22 de 0xef overschrijft.

maar

In C, de volgorde van bytes in een int zijn niet gedefinieerd. Dit programma overschrijft de 0xef met 0x22 op mijn Mac, maar er zijn andere platforms waar het de 0xde in plaats daarvan zou overschrijven, in plaats daarvan van de bytes die de int waren, werden omgekeerd. Daarom moet u bij het schrijven van een programma nooit vertrouwen op het gedrag van het overschrijven van specifieke gegevens in een vakbond omdat het niet draagbaar is.

Voor meer lezen op het bestellen van bytes, kijk uit endianness .


Antwoord 2, Autoriteit 12%

Hier is het korte antwoord: een struct is een recordstructuur: elk element in de structuur wijst de nieuwe ruimte toe. Dus, een struct als

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

wijst ten minste (sizeof(int)+sizeof(long)+sizeof(double)+sizeof(long double))bytes toe aan het geheugen voor elke instantie. (“Tenminste” omdat beperkingen van de architectuuruitlijning de compiler kunnen dwingen om de struct op te vullen.)

Aan de andere kant,

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

wijst één stuk geheugen toe en geeft het vier aliassen. Dus sizeof(union foobarbazquux_u) ≥ max((sizeof(int),sizeof(long),sizeof(double),sizeof(long double)), opnieuw met de mogelijkheid van enige toevoeging voor uitlijningen.


Antwoord 3, autoriteit 8%

Is er een goed voorbeeld om het verschil te geven tussen een ‘struct’ en een ‘unie’?

Een denkbeeldig communicatieprotocol

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

In dit denkbeeldige protocol is bepaald dat, op basis van het “berichttype”, de volgende locatie in de kop een verzoeknummer zal zijn, of een code van vier tekens, maar niet beide. Kortom, unies maken het mogelijk dat dezelfde opslaglocatie meer dan één gegevenstype vertegenwoordigt, waarbij het gegarandeerd is dat u slechts één van de soorten gegevens tegelijk wilt opslaan.

Unions zijn grotendeels een detail op laag niveau, gebaseerd op de erfenis van C als systeemprogrammeertaal, waar soms “overlappende” opslaglocaties op deze manier worden gebruikt. U kunt soms vakbonden gebruiken om geheugen te besparen als u een gegevensstructuur hebt waarin slechts één van de verschillende typen tegelijk wordt opgeslagen.

Over het algemeen geeft het besturingssysteem niets om structs en vakbonden, het zijn beide gewoon geheugenblokken. Een struct is een geheugenblok waarin verschillende gegevensobjecten zijn opgeslagen, waarbij deze objecten elkaar niet overlappen. Een unie is een geheugenblok waarin meerdere data-objecten zijn opgeslagen, maar alleen voor de grootste hiervan, en dus slechts één van de data-objecten tegelijk kan opslaan.


Antwoord 4, autoriteit 5%

Zoals je al aangeeft in je vraag, is het belangrijkste verschil tussen unionen structdat leden van unionelkaars geheugen overlappen, zodat dat de grootte van een vakbond die is, terwijl struct-leden achter elkaar worden opgemaakt (met optionele opvulling ertussen). Een vakbond is ook groot genoeg om al haar leden te bevatten, en heeft een opstelling die bij al haar leden past. Laten we zeggen dat intalleen kan worden opgeslagen op adressen van 2 bytes en 2 bytes breed is, en dat lang alleen kan worden opgeslagen op adressen van 4 bytes en 4 bytes lang is. De volgende vakbond

union test {
    int a;
    long b;
}; 

zou een sizeofvan 4 kunnen hebben, en een uitlijnvereiste van 4. Zowel een unie als een struct kunnen opvulling hebben aan het einde, maar niet aan het begin. Het schrijven naar een struct verandert alleen de waarde van het lid waarnaar wordt geschreven. Schrijven naar een lid van een vakbond maakt de waarde van alle andere leden ongeldig. Je hebt er geen toegang toe als je ze niet eerder hebt geschreven, anders is het gedrag niet gedefinieerd. GCC biedt als een extensie die u daadwerkelijk kunt lezen van leden van een vakbond, ook al heeft u hen de laatste tijd niet geschreven. Voor een besturingssysteem hoeft het niet uit te maken of een gebruikersprogramma naar een vakbond of naar een structuur schrijft. Dit is eigenlijk alleen een kwestie van de compiler.

Een andere belangrijke eigenschap van union en struct is dat ze toestaan dat een verwijzing ernaar kan verwijzen naar typen van elk van zijn leden. Dus het volgende is geldig:

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

some_test_pointer kan verwijzen naar int*of double*. Als je een adres van het type testnaar int*cast, verwijst het naar het eerste lid, a, eigenlijk. Hetzelfde geldt ook voor een vakbond. Dus, omdat een vakbond altijd de juiste uitlijning heeft, kun je een vakbond gebruiken om te verwijzen naar een type geldig:

union a {
    int a;
    double b;
};

Die vakbond kan in feite naar een int en een double verwijzen:

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

is in feite geldig, zoals vermeld in de C99-standaard:

De opgeslagen waarde van een object kan alleen worden benaderd door een lvalue-expressie die een van de volgende typen heeft:

  • een type dat compatibel is met het effectieve type van het object
  • een aggregaat- of vakbondstype dat een van de bovengenoemde typen onder zijn leden omvat

De compiler optimaliseert de v->a = 10;niet omdat dit de waarde van *some_int_pointerkan beïnvloeden (en de functie retourneert 10in plaats van 5).


Antwoord 5, autoriteit 3%

Een unionis nuttig in een aantal scenario’s.
unionkan een hulpmiddel zijn voor manipulatie op zeer laag niveau, zoals het schrijven van apparaatstuurprogramma’s voor een kernel.

Een voorbeeld daarvan is het ontleden van een floatgetal door gebruik te maken van unionvan een structmet bitfields en een float. Ik sla een nummer op in de floaten later heb ik toegang tot bepaalde delen van de floatvia die struct. Het voorbeeld laat zien hoe unionwordt gebruikt om gegevens vanuit verschillende hoeken te bekijken.

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

Bekijk de enkele precisiebeschrijving op wikipedia. Ik gebruikte het voorbeeld en het magische getal 0.15625 vanaf daar.


unionkan ook worden gebruikt om een algebraïsch gegevenstype te implementeren dat meerdere alternatieven heeft. Ik vond daar een voorbeeld van in het boek “Real World Haskell” van O’Sullivan, Stewart en Goerzen.
Bekijk het in het gedeelte De gediscrimineerde vakbond.

Proost!


Antwoord 6, autoriteit 2%

union” en “struct” zijn constructiesvan de C-taal. Het is ongepast om te praten over een verschil op “OS-niveau”, aangezien het de compileris die verschillende code produceert als u een of ander zoekwoord gebruikt.


Antwoord 7, autoriteit 2%

Je hebt het, dat is alles.
Maar wat hebben vakbonden eigenlijk voor zin?

U kunt inhoud van verschillende typen op dezelfde locatie plaatsen. Je moet het type wetenvan wat je in de union hebt opgeslagen (je plaatst het zo vaak in een structmet een type-tag…).

Waarom is dit belangrijk? Niet echt voor ruimtewinst. Ja, je kunt wat bits winnen of wat opvulling doen, maar dat is niet meer het belangrijkste punt.

Het is voor typeveiligheid, het stelt je in staat om een soort van ‘dynamisch typen’ te doen: de compiler weet dat je inhoud verschillende betekenissen kan hebben en de precieze betekenis van hoe je het interpreteert, is aan jou tijdens runtime. Als je een aanwijzer hebt die naar verschillende typen kan verwijzen, MOET je een unie gebruiken, anders kan je code onjuist zijn vanwege aliasingproblemen (de compiler zegt tegen zichzelf “oh, alleen deze aanwijzer kan naar dit type verwijzen, dus ik kan optimaliseren uit die toegangen…”, en er kunnen slechte dingen gebeuren).


Antwoord 8, autoriteit 2%

Niet technisch gesproken betekent:

Aanname: stoel = geheugenblok , mensen = variabel

Structuur: als er 3 personen zijn, kunnen ze dienovereenkomstig in een stoel van hun grootte zitten.

Union: als er 3 mensen zijn slechts éénstoel is er om te zitten, moeten ze allemaal dezelfde stoel gebruiken als ze willen zitten.

Technisch gezien betekent:

Het onderstaande programma geeft een diepe duik in structuur en eenheid samen.

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

Totale main_struct size = size van (uint64) voor bufferaddr + sizeof (unit32) voor Union + 32 bit voor opvulling (afhankelijk van processorarchitectuur) = 128 bits.
Voor structuur krijgen alle leden het geheugenblok aansluitbaar.

Union krijgt één geheugenblok van het MAX-formaatdeel (hier zijn 32 bit).
Inside Union One More Structure Lies (Inner_struct) De leden krijgen een geheugenblok van de totale maat 32 bits (16 + 8 + 8). In Union Inner_struct (32 bit) lid of gegevens (32 bit) zijn toegankelijk.


Antwoord 9, Autoriteit 2%

Ja, het belangrijkste verschil tussen struct en unie is hetzelfde als u vermeldde.
Structing gebruikt al het geheugen van haar lid en Unie gebruikt de grootste ledengeheugenruimte.

Maar al het verschil ligt door het gebruik van het geheugen.
Beste gebruik van de Unie is te zien in de processen van Unix, waar we gebruik maken van signalen.
Zoals een proces kan optreden op slechts één signaal tegelijk.
Dus de algemene verklaring zal zijn:

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

In dit geval maakt het proces gebruik van alleen het hoogste geheugen van alle signalen.
Maar als u in dit geval struct gebruikt, is het geheugengebruik van alle signalen.
Maakt veel verschil.

Om samen te vatten, moet de Unie worden geselecteerd als u weet dat u een van het lid tegelijk bereikt.


Antwoord 10

Een structuur wijst de totale grootte van alle elementen erin toe.

Een unie wijst alleen zoveel geheugen toe als het grootste lid vereist.


Antwoord 11

Wat is het verschil tussen structuur en unie?

Het kortere antwoord is: de eerbied zit in het toewijzen van geheugen.
Uitleg:
In de structuur wordt geheugenruimte gecreëerd voor alle leden binnen de structuur.
In union wordt alleen geheugenruimte gecreëerd voor een lid dat de meeste geheugenruimte nodig heeft.
Overweeg de volgende code:

struct s_tag
{
   int a; 
   long int b;
} x;
union u_tag
{
   int a; 
   long int b;
} y;

Hier zijn er twee leden binnen struct en unie: int en long int. Geheugenruimte voor int is: 4 byte en Geheugenruimte voor lange int is: 8 in 32-bits besturingssysteem.

Dus voor struct worden 4+8=12 bytes gemaakt terwijl 8 bytes worden gemaakt voor union

Codevoorbeeld:

#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-programmering/structure-and-union/


Antwoord 12

Het gebruik van vakbond
Vakbonden worden vaak gebruikt wanneer gespecialiseerde typegesprekken nodig zijn.
Om een idee te krijgen van het nut van vereniging. De standaardbibliotheek van c/c definieert geen functie die specifiek is ontworpen om korte gehele getallen naar een bestand te schrijven. Het gebruik van fwrite() brengt buitensporige overhead met zich mee voor een eenvoudige bediening. Met behulp van een unie kunt u echter eenvoudig een functie maken die een binair getal van een kort geheel getal met één byte per keer naar een bestand schrijft. Ik neem aan dat korte gehele getallen 2 byte lang zijn

HET VOORBEELD:

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

hoewel ik putw() heb aangeroepen met een kort geheel getal, was het mogelijk om putc() en fwrite() te gebruiken. Maar ik wilde een voorbeeld laten zien om te domineren hoe een vakbond kan worden gebruikt


Antwoord 13

structuur is een verzameling van verschillende gegevenstypes waar verschillende soorten gegevens in kunnen voorkomen
en iedereen krijgt zijn eigen geheugenblok

we gebruikten meestal union als we er zeker van zijn dat slechts één van de variabelen tegelijk zal worden gebruikt en je volledig gebruik wilt maken van het huidige geheugen omdat het maar één geheugenblok krijgt dat gelijk is aan het grootste type.

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

totaal geheugen krijgt =>5 byte

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

totaal geheugen krijgt =4 byte


Antwoord 14

Unions zijn handig bij het schrijven van een byte-ordeningsfunctie die hieronder wordt gegeven. Het is niet mogelijk met 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.

Antwoord 15

Een unie is anders dan een structuur als een Unie herhaalt over de anderen: het herdefinieert hetzelfde geheugen terwijl de struct een na de ander met geen overlappingen of herdefinities definieert.

Other episodes