Mógłby ktoś mi wytłumaczyć czym się różnią między sobą te dwa typy? Bo wyglądają tak samo.
No nie. Jak w uni masz chara i inta to możesz odczytać tylko chara albo tylko inta. Nigdy oba na raz.
Precyzyjniej mówiąc, poszczególne elementy unii zajmują ten sam obszar pamięci.
W rekordzie/strukturze masz dostęp do wszystkich elementów na raz, ponieważ każdy z nich znajduje się w innym obszarze pamięci. Przykładowo wygląda to tak:
bajty[1..4] = pole A
bajty[5..8] = pole B
bajty[9..16] = pole C
W przypadku unii dane te są upakowane w jednym miejscu (a sama unia ma rozmiar największego pola):
bajty[1..8] = pole A oraz pole B oraz pole C
lub nieco bardziej obrazowo:
bajty[1..4] = pole A
bajty[1..4] = pole B
bajty[1..8] = pole C
Czyli pod względem ilości zajmowanej pamięci lepsza jest unia, ale pod względem dostępu to lepsza jest struktura tak?
A do czego stosuje się te unie.
Bardziej przydatne wydają mi się struktury.
Intuicyjnie: unie stosuje się gdy używasz w danym momencie tylko jednego pola.
Mniej intuicyjnie: unie można zastosować do rzutowania, np zapisujemy do tablicy charów, a odczytujemy tablicę intów, itd
Mimo wszystko z unii rzadko kiedy się korzysta, bo rzadko kiedy mają sens. Struktury są uniwersalne.
A do czego stosuje się te unie.
Bardziej przydatne wydają mi się struktury.
Przypuśćmy, że masz strukturę w stylu:
struct Struktura {
int typ_danych;
int dane_a;
float dane_b;
char[10] dane_c;
}
I przykładowo używasz jej do przesyłania danych od swojego programu-klienta do programu-serwera (czyli przez sieć).
Jako, że w zależności od pola typ_danych
użyte będzie albo dane_a
, albo dane_b
, albo dane_c
, możesz zaoszczędzić pamięć i zrobić unię, ponieważ nigdy nie będzie użyte zarówno pole np.dane_a
i dane_c
, a zawsze w jednym pakiecie tylko jedno z tych trzech:
struct Struktura {
int typ_danych;
union {
int dane_a;
float dane_b;
char[10] dane_c;
}
}
No i bywają jeszcze przydatne w rzutowaniu, jak wspomniał @Wibowit.
Mniej intuicyjnie: unie można zastosować do rzutowania, np zapisujemy do tablicy charów, a odczytujemy tablicę intów, itd
Nie za bardzo można. W C++ to jest undefined behavior. O dziwo w C99 i C11 można to niby robić, ale nie musi działać.