Union neboli sjednocení Bitová pole
Struktura datový typ s heterogenními položkami pro každou položku je rezervováno místo v paměti typedef struct { int cislo; char zn; } TUkazkova; TUkazkova s;
nechť sizeof(int)=4 s.zn s.cislo s
Union (sjednocení) datový typ s heterogenními položkami místo v paměti je rezervováno pouze pro nejdelší položku položky se překrývají v daném okamžiku je platná pouze jedna položka union neposkytuje informaci, která položka byla použita
typedef union { int cislo; char zn; } TUksjedn; TUksjedn u;
nechť sizeof(int)=4 u.cislo u.zn u
uniony se příliš často nepoužívají důvody použití šetření paměti např. ve velkých polích variantní záznam chceme-li se na jeden datový typ „podívat“ několika způsoby, což je implementačně závislé a program pak nemusí být přenositelný
Variantní záznam musím deklarovat jako strukturu s položkami pevnými rozlišovací varianta, což je položka typu union
Příklad: nákladní a osobní auto typedef enum {OS, NAKL} TypA; typedef union { float nosnost; int pocet_osob; } Parametry; typedef struct { char SPZ[7]; /*spol. polozka */ TypA typ; /* rozhodovaci polozka */ Parametry param; } TAuto;
TAuto auta[10]; auto[0].typ = OS; auto[0].param.pocet_osob = 4; auto[1].typ = NAKL; auto[1].param.nosnost = 4; výraz auto[1].param.pocet_osob překladač akceptuje, ale je logicky nesprávný
položky sjednocení mohou být i struktury typedef struct {float f, float g} TDes; typedef struct {int i, int j} TCela; typedef union { TDes d; TCela c; } TOboje; TOboje o; o.c.i = 3; o.d.g = 4.55;
Příklad: předpokládáme opět velikost typu int 4 slabiky typedef union { int x; struct { unsigned char b0; unsigned char b1; unsigned char b2; unsigned char b3; } slabiky; } TKukatko;
TKukatko k; k.slabiky.b3 k.slabiky.b2 k.x k.slabiky.b1 k.slabiky.b0
na nultou slabiku se „podívám“: k.slabiky.b0; přiřazení hodnoty k x: k.x = 328; na nultou slabiku se „podívám“: k.slabiky.b0; ale pouze u procesorů Intel, protože nemám zaručeno, že položka b0 bude odpovídat slabice nižšího řádu u překladačů pro procesory s uložením big endian (např. Motorola) se takto „podívám“ naopak na slabiku nejvyššího řádu překladač může upravit hranice mezi položkami záleží na překladači a platformě (procesoru)
Bitová pole
Bitové pole struktura, jejíž velikost je omezena velikostí typu int (maximálně) minimální velikost jedné položky je 1 bit vhodné pro přístup pomocí k bitům pomocí identifikátorů používáme tam, kde chceme ušetřit paměť používané zejména u překladačů jazyka C pro jednočipové mikropočítače
Příklad: typedef struct { unsigned int den :5; /* bity 0 až 4 */ unsigned int mesic :4; /* bity 5 až 8 */ unsigned int rok :23; /* bity 9 až 31 */ } TDatum; TDatum datum; datum.den = 12;
Příklad: příznakový registr OPTION jednočipového mikropočítače PIC typedef struct { unsigned int PS0 :1; unsigned int PS1 :1; unsigned int PS2 :1; unsigned int PSA :1; unsigned int RTE :1; unsigned int RTS :1; } TOption;
TOption option at xxxx; deklaruji proměnnou na příslušnou adresu TOption option at xxxx; některé překladače pro jednočipové procesory mají direktivu např. at, @, která umožňuje mapovat proměnnou na konkrétní adresu do paměti k jednotlivým bitům přistupuji „normálně“, nemusím používat masku a logické operace if (option.PSA == 1)
pokud bych chtěl přistupovat k bitům PS jako ke trojici, resp pokud bych chtěl přistupovat k bitům PS jako ke trojici, resp. k celému registru, nadeklaruji sjednocení struktur typedef struct { unsigned int PS :3; unsigned int PSA :1; unsigned int RTE :1; unsigned int RTS :1; } TOption2; typedef union { TOption o1; TOption2 o2; unsigned char cely; } TOptionReg;
přístup k celému registru přístup k hodnotě PS přístup k bitu RTS TOptionReg registr at xxxx; přístup k celému registru registr.cely = 0x20; přístup k hodnotě PS registr.o2.PS = 0x03; přístup k bitu RTS registr.o2.RTS = 1; nebo registr.o1.RTS = 1;