Nu există nici un bun exemplu pentru a da diferența dintre o struct
și o "uniune"?
Practic, știu că struct
foloseste toate memoria sale membre și "uniune" folosește mai mare de membri ai spațiu de memorie. Este o orice alt sistem de OPERARE diferenta de nivel?
Cu o uniune, ai're doar ar trebui să utilizați unul dintre elemente, deoarece acestea're toate stocate în același loc. Acest lucru îl face util atunci când doriți să stocați ceva care ar putea fi una dintre mai multe tipuri. Un struct, pe de altă parte, are separat o locație de memorie pentru fiecare din elementele sale și toate acestea pot fi folosite la o dată.
Pentru a da un exemplu concret de utilizare a acestora, am fost de lucru pe un Sistem de interpret puțin timp în urmă și am fost, în esență, suprapunerea Schemei de tipuri de date pe C tipuri de date. Acest lucru a implicat stocarea într-un struct un enum indică tipul de valoare și o uniune pentru a stoca valoarea respectivă.
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: Daca're vă întrebați la ce setare x.b 'c' schimbă valoarea lui x.o să, tehnic vorbind's nedefinit. Pe cele mai moderne mașini de un char 1 octet și un int este de 4 bytes, deci oferindu-x.b valoarea 'c' oferă, de asemenea, primul octet din x.o aceeași valoare:
union foo x;
x.a = 3;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);
printuri
99, 99
De ce sunt cele două valori la fel? Pentru ultimii 3 octeți de int 3 sunt toate zero, deci's, de asemenea, citit ca 99. Dacă punem într-un număr mai mare de x.o, tu'll vedea că acest lucru nu este întotdeauna cazul:
union foo x;
x.a = 387439;
x.b = 'c';
printf("%i, %i\n", x.a, x.b);
printuri
387427, 99
Pentru a obține o privire mai atentă la memoria reală a valorilor, să's a stabilit și imprima valorile în hex:
union foo x;
x.a = 0xDEADBEEF;
x.b = 0x22;
printf("%x, %x\n", x.a, x.b);
printuri
deadbe22, 22
Puteți vedea în mod clar unde 0x22 suprascris 0xEF.
DAR
În C, ordinea de octeți într-un int sunt nu este definit. Acest program suprascris 0xEF cu 0x22 pe Mac-ul meu, dar există și alte platforme unde s-ar suprascrie 0xDE în loc pentru că ordinea de bytes care alcătuiesc int s-au inversat. Prin urmare, atunci când scrieți un program, niciodată nu ar trebui să se bazeze pe comportamentul de suprascriere date specifice într-o uniune, deoarece's nu portabil.
Pentru mai mult de lectură pe ordinea de bytes, a verifica afară endianness.
Aici's scurt raspuns: struct este un record structura: fiecare element în struct alocă spațiu nou. Deci, ca o struct
struct foobarbazquux_t {
int foo;
long bar;
double baz;
long double quux;
}
alocă cel puțin (sizeof(int)+sizeof(long)+sizeof(double)+sizeof(long double))
octeți în memorie pentru fiecare instanță. ("de Cel puțin" pentru arhitectura constrângerile de aliniere poate forța compilator pentru a pad struct.)
Pe de altă parte,
union foobarbazquux_u {
int foo;
long bar;
double baz;
long double quux;
}
alocă o bucată de memorie și oferă patru pseudonime. Deci, sizeof(uniunea foobarbazquux_u) ≥ max((sizeof(int),sizeof(long),sizeof(double),sizeof(long double))`, din nou, cu posibilitatea de a un plus pentru aliniamente.
nu există nici un bun exemplu pentru a da diferența dintre o 'struct' o 'uniunea'?
Un imaginar protocol de comunicare
struct packetheader {
int sourceaddress;
int destaddress;
int messagetype;
union request {
char fourcc[4];
int requestnumber;
};
};
În acest imaginar protocol, a fost sepecified că, pe baza "mesaj de tip", următoarea locație în antetul va fi o cerere număr sau un cod de patru caractere, dar nu ambele. Pe scurt, sindicatele permite pentru aceeași locație de stocare pentru a reprezenta mai mult decât un singur tip de date, în cazul în care este garantat că va doresc doar pentru a stoca unul dintre tipurile de date la un moment dat.
Sindicatele sunt, în mare măsură, un nivel scăzut detaliu cu sediul în C's patrimoniului ca un sistem limbaj de programare, în cazul în care "se suprapun" locurile de depozitare sunt folosite uneori în acest fel. Puteți utiliza, uneori, sindicatele pentru a salva de memorie în cazul în care aveți o structură de date în cazul în care doar unul dintre mai multe tipuri vor fi salvate la un moment dat.
În general, sistemul de OPERARE nu't de îngrijire sau știu despre struct și sindicatele-ei sunt pur și simplu ambele blocuri de memorie pentru a-l. O struct este un bloc de memorie care stochează mai multe obiecte de date, în cazul în care aceste obiecte nu't se suprapun. O uniune este un bloc de memorie care stochează mai multe obiecte de date, dar are numai de depozitare pentru cel mai mare dintre acestea, și, astfel, pot stoca doar unul dintre obiectele de date la un moment dat.
Ca deja ai stat în întrebarea dumneavoastră, principala diferență între "uniune" și struct
este ca "uniunea" membrii suprapunere memoria de celălalt, astfel încât sizeof de o uniune este una , în timp ce struct
membrii sunt prevăzute unul după altul (opțional cu umplutură în între). De asemenea, o uniune este suficient de mare pentru a conține toți membrii săi, și au o aliniere care se potrivește tuturor membrilor săi. Deci sa's spun int
pot fi depozitate doar la 2 octet adrese și este de 2 octeți largi și lungi pot fi depozitate doar la 4 octet adrese și este de 4 bytes lung. Următoarele uniunii
union test {
int a;
long b;
};
ar putea avea un sizeof
de 4, și o aliniere cerința a 4. Atât o uniune și o struct poate fi padding la sfârșitul anului, dar nu la începutul lor. Scris de la un struct schimbă doar valoarea statele scris. Scris de la un membru de sindicat se va face la valoarea de toți ceilalți membri ai invalid. Tu nu le pot accesa, dacă te-ai't scris pentru a-i înainte, în caz contrar, comportamentul este nedefinit. GCC prevede ca o extensie care le puteți citi de fapt, de la membrii de sindicat, chiar dacă te-ai't scris pentru ei cel mai recent. Pentru un Sistem de Operare, nu't trebuie să conteze dacă un utilizator program scrie la un sindicat sau la o structură. Acest fapt este doar o problemă de compilator.
O altă proprietate importantă a uniunii și struct este, ele permit ca un pointer la le poate indica tipurile de oricare dintre membrii săi. Deci, următoarele este valabilă:
struct test {
int a;
double b;
} * some_test_pointer;
some_test_pointer poate indica int* " sau " dublu*
. Dacă ați aruncat o adresă de tip "test" pentru a int*
, se va indica în primul său membru, "a", de fapt. Același lucru este valabil și pentru o uniune prea. Astfel, pentru o uniune va avea întotdeauna dreptul de aliniere, puteți utiliza o uniune pentru a face arătând spre un tip valabil:
union a {
int a;
double b;
};
Că uniunea va fi de fapt în măsură să punct la un int, și un dublu:
union a * v = (union a*)some_int_pointer;
*some_int_pointer = 5;
v->a = 10;
return *some_int_pointer;
este de fapt valabil, după cum a afirmat C99 standard:
Un obiect trebuie să aibă valoare stocată accesate numai de către un lvalue expresie care are unul din următoarele tipuri:
- un tip compatibil cu efective tip de obiect
- ...
- un agregat sau o uniune de tip, care include unul dintre tipurile de mai sus, printre membrii săi
Compilatorul câștigat't optimiza out v->a = 10;
, deoarece ar putea afecta valoarea *some_int_pointer
(și funcția va reveni 10 "în loc de" 5
).
O "uniune" este utilă în două scenarii. "uniune" poate fi un instrument de nivel foarte scăzut de manipulare place să scriu drivere de dispozitiv pentru un kernel.
Un exemplu de care este diseca un "float" numărul apeland la "uniune" de o struct
cu bitfields și un "float". Am salva un număr în "float", iar mai târziu pot accesa anumite părți ale "float" prin care struct
. Exemplul arată cum "uniune" este folosit pentru a avea unghiuri diferite pentru a uita-te la date.
#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;
}
Uită-te la singur precizie descriere de pe wikipedia. Am folosit exemplul și numărul magic 0.15625 de acolo.
"uniune" poate fi, de asemenea, utilizat pentru a implementa o algebrice tip de date care are mai multe alternative. Am găsit un exemplu în "din Lumea Reală Haskell" cartea de O'Sullivan, Stewart, și Goerzen. Check it out în discriminate uniunii secțiune.
Noroc!
Non tehnic vorbind, înseamnă :
Ipoteza: scaun = bloc de memorie , oamenii = variabilă
Structura : Dacă există 3 persoane pot sta în scaunul de dimensiunea lor în mod corespunzător .
Uniunii : Dacă există 3 persoane singurul scaun va fi acolo să stea , toate trebuie să utilizeze același scaun atunci când doresc să se așeze .
Din punct de vedere tehnic înseamnă :
Menționate mai jos programul vă oferă o scufundare adânc în structura și uniunea împreună .
struct MAIN_STRUCT
{
UINT64 bufferaddr;
union {
UINT32 data;
struct INNER_STRUCT{
UINT16 length;
UINT8 cso;
UINT8 cmd;
} flags;
} data1;
};
Total MAIN_STRUCT size =sizeof(UINT64) pentru bufferaddr + sizeof(UNIT32) pentru uniunea + 32 de biți pentru umplutură(depinde de arhitectura procesorului) = 128 de biți . Pentru structura toți membrii obține bloc de memorie adiacent .
Uniunea devine un bloc de memorie de dimensiune max membru(Aici 32 de biți) . În interiorul uniunii unul mai mult structura de minciuni(INNER_STRUCT) membrii săi a obține un bloc de memorie de dimensiune totală de 32 de biți(16+8+8) . În uniune fie INNER_STRUCT(32 bit) membru sau a datelor(32 de biți) pot fi accesate .
"uniunii" și "struct" de construcții de C limba. Vorbim de un "sistem de OPERARE de nivel" diferența dintre ele este inadecvat, deoarece's a compilator care produce cod diferit dacă utilizați unul sau un alt cuvânt-cheie.
Da, principala diferență dintre struct și union este același ca ai precizat. Struct foloseste toate memoria sale membre și ale uniunii folosește mai mare de membri ai spațiu de memorie.
Dar diferența constă de utilizare nevoie de memorie. Cel mai bun de utilizare al uniunii poate fi văzut în procesele de unix unde vom face uz de semnale. ca un proces poate acționa asupra unui singur semnal la un moment dat. Deci, declarația generală va fi:
union SIGSELECT
{
SIGNAL_1 signal1;
SIGNAL_2 signal2;
.....
};
În acest caz, procesul folosi doar cea mai mare memorie de toate semnalele. dar, dacă folosiți struct în acest caz, utilizarea de memorie va fi suma tuturor semnalelor. Face o mulțime de diferență.
Pentru a rezuma, Uniunea ar trebui să fie selectate, dacă știi că ai acces la oricare dintre statele la un moment dat.
Ai, ca's toate. Dar așa, de fapt, ceea ce's punctul de sindicate?
Puteți pune în aceeași locație, conținut de diferite tipuri. Trebuie să știu tipul de ce le-ați stocat în uniune (atât de des l-ai pus într-o struct
cu un tip de tag-ul...).
De ce este important acest lucru? Nu chiar pentru spațiu de câștiguri. Da, puteți obține unele biți sau de a face unele de umplutură, dar care's nu principalul punct mai.
L's de tip siguranță, vă permite să facă un fel de 'dinamice': compilatorul știe că conținutul dvs. poate avea diferite semnificații și semnificația exactă a modului de a interpreta este de până la tine la run-time. Dacă aveți un pointer care poate indica diferite tipuri, TREBUIE să utilizați o uniune, altfel codul poate fi incorectă din cauza aliasing probleme (compilatorul spune de la sine "oh, doar acest pointer poate indica acest tip, așa că am putea optimiza acele accese...", și se pot întâmpla lucruri rele).
care este diferenta dintre structuri si uniuni?
Tăiat scurt, răspunsul este: respectul este în alocarea de memorie. Explicație: În structură, spațiu de memorie va fi creat pentru toți membrii în interiorul structurii. În uniunea spațiu de memorie va fi creat doar pentru un membru care are nevoie de cel mai mare spațiu de memorie. Luați în considerare următorul cod:
struct s_tag
{
int a;
long int b;
} x;
union u_tag
{
int a;
long int b;
} y;
Aici există două membrii în interiorul struct și union: int și long int. Spațiu de memorie pentru int este: 4 octet și spațiu de Memorie pentru mult timp int este: 8 la 32 de biți sistem de operare.
Deci, pentru struct 4+8=12 bytes va fi creat în timp ce 8 bytes va fi creat pentru uniune
Exemplu de cod:
#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-programare/structura și uniunii/
o structură este o colecție de diferite tip de date în cazul în care diferite tipuri de date pot locui în ea și fiecare avea propria bloc de memorie
noi, de obicei, utilizate în uniune atunci când suntem siguri că doar una dintre variabile vor fi folosite la o dată și vă doresc pe deplin utilizarea de prezent de memorie pentru a primi doar un singur bloc de memorie care este egal cu cel mai mare tip.
struct emp
{
char x;//1 byte
float y; //4 byte
} e;
memorie totală l =>5 octet
union emp
{
char x;//1 byte
float y; //4 byte
} e;
memorie totală l =4 byte
Utilizări ale uniunii Sindicatele sunt utilizate frecvent atunci când specializate de tip conversații sunt necesare. Pentru a obține o idee de utilitatea uniunii. C/c standard library nu definește nici o funcție special conceput pentru a scrie scurt numere întregi într-un fișier. Folosind fwrite() suportă encurs excesivă aeriene pentru operație simplă. Cu toate acestea, folosind o uniune puteți crea cu ușurință o funcție care scrie binare de un scurt număr întreg într-un fișier un octet la un moment dat. Presupun că scurt numere întregi sunt 2 octet mult
DE EXEMPLU:
#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);
}
deși putw() am sunat cu o scurtă întreg, a fost possble de a utiliza putc() și fwrite(). Dar am vrut să arăt un exemplu pentru dominstrate cum o uniune poate fi folosit
Sindicatele veni la îndemână în timp ce scrierea unui octet funcția de comandă care este dat de mai jos. L's nu este posibil cu struct.
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.
O Uniune este diferit de la o struct ca o Uniune repetă de-a lungul altele: redefinește fel de memorie în timp struct definește unul după celălalt, fără suprapuneri sau redefinitions.