Unia można zdefiniować jako typ danych zdefiniowany przez użytkownika, który jest zbiorem różnych zmiennych różnych typów danych w tym samym miejscu pamięci. Unię można również zdefiniować jako wiele elementów, ale tylko jeden element może zawierać wartość w określonym momencie.
Unia to typ danych zdefiniowany przez użytkownika, ale w przeciwieństwie do struktur mają tę samą lokalizację w pamięci.
Rozumiemy to na przykładzie.
struct abc { int a; char b; }
Powyższy kod jest strukturą zdefiniowaną przez użytkownika, która składa się z dwóch elementów, tj. typu „a”. wew i typu „b”. postać . Kiedy sprawdziliśmy adresy „a” i „b”, odkryliśmy, że ich adresy są różne. Dlatego dochodzimy do wniosku, że elementy struktury nie mają tej samej lokalizacji w pamięci.
Kiedy definiujemy unię, odkryliśmy, że unię definiuje się w taki sam sposób, jak definiuje się strukturę, z tą różnicą, że słowo kluczowe union służy do definiowania typu danych union, podczas gdy słowo kluczowe struct służy do definiowania struktury. Unia zawiera elementy danych, tj. „a” i „b”. Kiedy sprawdzimy adresy obu zmiennych, okaże się, że obie mają te same adresy. Oznacza to, że członkowie związku mają to samo miejsce w pamięci.
Przyjrzyjmy się obrazowej reprezentacji alokacji pamięci.
Poniższy rysunek przedstawia poglądowe przedstawienie konstrukcji. Struktura ma dwóch członków; tj. jeden jest typu całkowitego, a drugi typu znakowego. Ponieważ 1 blok jest równy 1 bajtowi; dlatego zmiennej „a” zostaną przydzielone 4 bloki pamięci, podczas gdy zmiennej „b” zostanie przydzielony 1 blok pamięci.
Poniższy rysunek przedstawia obrazowe przedstawienie członków związku. Obie zmienne dzielą tę samą lokalizację w pamięci i mają ten sam adres początkowy.
W związku członkowie będą dzielić lokalizację pamięci. Jeśli spróbujemy wprowadzić zmiany u któregokolwiek członka, zostanie to odzwierciedlone również w drugim członku. Rozumiemy tę koncepcję na przykładzie.
union abc { int a; char b; }var; int main() { var.a = 66; printf(' a = %d', var.a); printf(' b = %d', var.b); }
W powyższym kodzie union ma dwóch członków, tj. „a” i „b”. „var” jest zmienną typu union abc. w główny() metodę, przypisujemy 66 do zmiennej „a”, więc var.a wyświetli 66 na ekranie. Ponieważ zarówno „a”, jak i „b” współdzielą lokalizację w pamięci, zmienna.b wydrukuję ' B ' (kod ascii 66).
Decydowanie o wielkości związku
Wielkość związku opiera się na wielkości największego członka związku.
Rozumiemy na przykładzie.
union abc{ int a; char b; float c; double d; }; int main() { printf('Size of union abc is %d', sizeof(union abc)); return 0; }
Jak wiemy, rozmiar int wynosi 4 bajty, rozmiar char wynosi 1 bajt, rozmiar float wynosi 4 bajty, a rozmiar double wynosi 8 bajtów. Ponieważ zmienna double zajmuje największą pamięć spośród wszystkich czterech zmiennych, w pamięci zostanie przydzielonych łącznie 8 bajtów. Dlatego wynik powyższego programu będzie wynosił 8 bajtów.
Dostęp do członków związku za pomocą wskaźników
Dostęp do członków związku możemy uzyskać poprzez wskaźniki, używając operatora strzałki (->).
Rozumiemy na przykładzie.
#include union abc { int a; char b; }; int main() { union abc *ptr; // pointer variable declaration union abc var; var.a= 90; ptr = &var; printf('The value of a is : %d', ptr->a); return 0; }
W powyższym kodzie utworzyliśmy zmienną wskaźnikową, tj. *ptr, która przechowuje adres zmiennej var. Teraz ptr może uzyskać dostęp do zmiennej „a” za pomocą operatora (->). Zatem wynik powyższego kodu będzie wynosił 90.
Dlaczego potrzebujemy związków C?
Rozważ jeden przykład, aby zrozumieć potrzebę związków C. Rozważmy sklep, który ma dwa produkty:
- Książki
- Koszule
Właściciele sklepów chcą przechowywać ewidencję ww. dwóch pozycji wraz z odpowiednimi informacjami. Na przykład Książki obejmują tytuł, autora, liczbę stron, cenę, a Koszule obejmują kolor, projekt, rozmiar i cenę. Właściwość „cena” jest wspólna w obu przedmiotach. Właściciel Sklepu chce przechowywać właściwości, a następnie sposób, w jaki będzie przechowywać zapisy.
Początkowo postanowiono przechowywać rekordy w strukturze pokazanej poniżej:
struct store { double price; char *title; char *author; int number_pages; int color; int size; char *design; };
Powyższa struktura składa się ze wszystkich pozycji, które właściciel sklepu chce przechowywać. Powyższa konstrukcja jest w pełni użytkowa, jednak cena jest wspólną własnością obu przedmiotów, a pozostałe elementy są indywidualne. Właściwości takie jak cena, *tytuł, *autor i liczba_stron należą do Książek, natomiast kolor, rozmiar i *wzór należą do Koszul.
Zobaczmy, jak możemy uzyskać dostęp do elementów struktury .
int main() { struct store book; book.title = 'C programming'; book.author = 'Paulo Cohelo'; book.number_pages = 190; book.price = 205; printf('Size is : %ld bytes', sizeof(book)); return 0; }
W powyższym kodzie utworzyliśmy zmienną typu sklep . Przypisaliśmy wartości do zmiennych: tytuł, autor, liczba_stron, cena, ale zmienna książka nie posiada właściwości takich jak rozmiar, kolor i wygląd. Dlatego jest to marnowanie pamięci. Rozmiar powyższej struktury wynosiłby 44 bajty.
Możemy zaoszczędzić dużo miejsca, jeśli zastosujemy związki.
#include struct store { double price; union { struct{ char *title; char *author; int number_pages; } book; struct { int color; int size; char *design; } shirt; }item; }; int main() { struct store s; s.item.book.title = 'C programming'; s.item.book.author = 'John'; s.item.book.number_pages = 189; printf('Size is %ld', sizeof(s)); return 0; }
W powyższym kodzie utworzyliśmy zmienną typu store. Ponieważ w powyższym kodzie użyliśmy sum, więc przy alokacji pamięci brana będzie pod uwagę największa pamięć zajmowana przez zmienną. Dane wyjściowe powyższego programu to 32 bajty. W przypadku struktur otrzymaliśmy 44 bajty, natomiast w przypadku unii uzyskany rozmiar wynosi 44 bajty. Dlatego 44 bajty to więcej niż 32 bajty, co pozwala zaoszczędzić dużo miejsca w pamięci.