Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole - uniony (sjednocení) Studijní materiály najdete na adrese:

Podobné prezentace


Prezentace na téma: "7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole - uniony (sjednocení) Studijní materiály najdete na adrese:"— Transkript prezentace:

1 7. přednáška práce se strukturami - bitové operace - bitová pole - uniony (sjednocení) Studijní materiály najdete na adrese:

2 struct {struct STRU { int k1, k2;float h, z; char *buf1;char pole[10]; } to_to; }; - oba způsoby lze libovolně kombinovat struct STRU s1, s2, s3; struct STRU { float h, z; char pole[10]; } a, b, c; - struktury lze při deklaraci inicializovat (podle K&R pouze externí a statické) { deklarace struktury} = { seznam inicializatoru }; Struktury

3 struct{ int a, b; char *c; int pole[5]; double d; } upoc = { 1, 2, “TEXT”, {1, 3, 5, 7, 9}, }; typedef struct{ char jmeno[25]; cgar trida; short podtrida; float dekl, rekt, vzdal; } hvezda; main() { hvezda moje_hvezda; strcpy(moje_hvezda.jmeno, “epsilon eridani”); moje_hvezda.trida = ‘K‘; moje_hvezda.podtrida = 4 ….. } Struktury

4 Příklady struktur struct { int vyska; float vaha; } pavel, honza, karel; struct miry { int vyska; float vaha; }; struct miry pavel; struct miry honza, karel; pozor, nelze !!! miry pavel, honza, karel; typedef struct { int vyska; float vaha; } MIRY; MIRY pavel, honza, karel; struct miry { int vyska; float vaha; } pavel, honza, karel; typedef struct miry{ int vyska; float vaha; } MIRY; MIRY pavel, honza, karel;

5 Struktury - jméno struktury je nepovinné, slouží pouze jako identifikátor šablony - je-li jméno nadefinováno, používáme je k pozdější deklaraci - nejsou-li při deklaraci specifikovány proměnné typu struktura, vytvoří se jen šablona se jménem - proměnné strukturovaných typů, které nemají jmenovku, nemůžeme předávat jako parametr funkce. - strukturu můžeme i inicializovat - do složených závorek napíšeme seznam hodnot proměnných obsažených ve struktuře - nemusíme inicializovat všechny prvky, lze vynechat prvky na konci struktury - struktury lze navzájem vnořovat (struktura nemůže obsahovat proměnnou svého vlastního typu)

6 - stejně jako u proměnných máme možnost deklarovat směrník na strukturu, je pro něj zaveden operátor ->, přináší možnost řetězit struktury, členem struktury nesmí být struktura stejného typu, přípustný je pouze směrník struct MOJE{ float a, b; int c; char *smer; }; struct MOJE da_da; struct MOJE *sm_moje; …….. sm_moje = calloc(1, sizeof(struct MOJE));struct TADY { ….. …… struct TADY a; struct TADY *a; …… ……. }; NE ANO Práce se strukturami

7 Ukazatel na strukturu - ukazatel na strukturu typedef struct { char jmeno[30]; int rocnik; } STUDENT; STUDENT s, *p_s; - alokování paměti: p_s = (STUDENT *) malloc(sizeof(STUDENT)); - inicializace směrníku: p_s = &s; - definice typu směrník na strukturu: typedef struct { char jmeno[30]; int rocnik; } STUDENT, *P_STUDENT; STUDENT s; P_STUDENT p_s; p_s = (P_STUDENT) malloc(sizeof(STUDENT));

8 Struktury - přístup k prvkům struktury, operátor. zpřístupňuje proměnné ze struktury - operátor -> zpřístupňuje proměnné ze struktury, na kterou máme ukazatel pavel.vyska = 190; pavel.vaha = karel.vaha; struct miry *p_karel; p_karel = &karel; p_karel->vyska = 184; (*p_karel).vyska = 184; často používáme pole struktur, nebo dynamické datové typy vytvořené jako spojové seznamy ze struktur - například binární strom: struct tree {struct tree *left;/* struct tree { struct tree b; … */ struct tree *right; } a;

9 Práce se strukturami - zpřístupnění prvku struktury se provádí přes proměnnou, nebo přes směrník da_da.a = 5.46; da_da.c = 3; da_da.b = da_da.a / da_da.c; sm_moje->a = 6.78; sm_moje->c = 7; sm_moje->b = sm_moje->a / sm_moje->c; sm_moje->smer = calloc(100, sizeof(char)); - další operace pro struktury jsou: získání adresy, přiřazení struktur stejného typu, parametr, návratová hodnota funkce - pro získání adresy se používá operátor &, deklarovaný směrník musí být generický nebo na strukturu stejného typu - jako parametr i návratová hodnota mohou být i směrníky na strukturu

10 Práce se strukturami

11 struct XXX {p=&v;/* ziskani adresy */ int a, b, c;x=v;/* prirazeni struktur */ float d; } v, x, *y;struct XXX fce(struct XXX m) { struct XXX z; struct XXX *p; ….. return z; } - v dalším příkladu nejsou struktury a, m, n formálně shodné, nel- ze je proto přiřazovat struct SSSR {struct { float b, f;float b, f; }; } a; struct SSSR m, n; - kompilátory pro normu ANSI mají možnost nastavit zarovnávání ukládání struktury na hranici slova, každá struktura potom začí- ná na sudé adrese, každý člen struktury jiného typu než char bude mít sudou relativní adresu vzhledem k začátku struktury

12 struct date { int day; int month; int year; int yesterday; char mon_name[4]; }; struct person { char name[NAMESIZE]; char addr[ADDRSIZE]; long zipcode; double salary; struct date birthdate; struct date hiredate; }; … struct person KAREL; … KAREL.birthdate.month /* odkaz na měsíc narození */ /* operátor kvalifikace se sdružuje*/ /* zleva doprava*/ Práce se strukturami

13 *m->y obsah místa, kam ukazuje y *m->x++ inkrementuje x po přístupu k místu, kam ukazuje (*p->y)++ inkrementuje obsah místa, kam ukazuje y p++->xinkrementuje p po přístupu k místu, kam ukazuje x struct {/* ++p->x inkrementuje x, nikoliv p, neboť */ int x;/* priorita zajistí provedení ++(p->x) */ int y; } *p;/* pro jiné vyhodnocení musíme změnit prioritu, */ /* (++p)->x inkrementace před dosažením x */ /* (p++)->x inkrementace po dosažení x */ Práce se strukturami struct { int *x; int *y; } *m;

14

15 #include #define ZNAKU_NAZEV 25 #define POLOZEK_ZBOZI 10 #define FORMAT_VYROBEK "cislo:%5d pocet:%5d cena:%10.2f nazev:%s\n" typedef struct {float re, im;} complex; typedef struct { int ev_cislo; char nazev[ZNAKU_NAZEV + 1]; int na_sklade; float cena; } vyrobek; typedef vyrobek zbozi[POLOZEK_ZBOZI]; int main(void) { complex cislo, im_jednotka = {0, 1}; zbozi polozky; vyrobek *ppolozky, a = {8765, "nazev zbozi na sklade", 100, }; cislo.re = ; cislo.im = ; polozky[0].ev_cislo = 0; strcpy(polozky[0].nazev, "polozka cislo 0"); polozky[0].na_sklade = 20; polozky[0].cena = 45.15;

16 ppolozky = polozky + 1; ppolozky->ev_cislo = 1; /* (*ppolozky).ev_cislo = 1; */ strcpy(ppolozky->nazev, "polozka cislo 1"); ppolozky->na_sklade = 123; ppolozky->cena = ; printf("re = %10.5f im = %10.5f\n", im_jednotka.re, im_jednotka.im); printf("re = %10.5f im = %10.5f\n", cislo.re, cislo.im); printf(FORMAT_VYROBEK, a.ev_cislo, a.na_sklade, a.cena, a.nazev); printf(FORMAT_VYROBEK, polozky[0].ev_cislo, polozky[0].na_sklade, polozky[0].cena, polozky[0].nazev); printf(FORMAT_VYROBEK, ppolozky->ev_cislo, ppolozky->na_sklade, ppolozky->cena, ppolozky->nazev); return 0; } Výstup získaný spuštěním programu: re = im = re = im = cislo: 8765 pocet: 100 cena: nazev:nazev zbozi na sklade cislo: 0 pocet: 20 cena: nazev:polozka cislo 0 cislo: 1 pocet: 123 cena: nazev:polozka cislo 1

17 Bitové operace & bitový součin | bitový součet ^ bitový exklusivní součet << posun doleva >> posun doprava ~ jedničkový doplněk

18 Bitová pole - pokud potřebujeme do jednoho slova uložit více než jeden objekt, používáme bitová pole, bitové pole je množina sousedních bitů v rámci proměnné typu int deklarace a použití takových proměnných je stejné jako u struktur, pouze u jednotlivých proměnných používáme operátor : pro stanovení počtu jednotlivých bitů struct flags { unsigned a:1; :2; /* zarovnání */ unsigned b:1; unsigned c:3; } flag; flag.a = 1; /* použití */ vynecháme-li jméno bitového pole, použijeme vyhrazené bity pouze jako výplň pro zarovnání specifická délka 0 se používá pro zarovnání na slovo bitové pole musí být typu int, signed int nebo unsigned int jednotlivé proměnné uvnitř bitového pole nemají své adresy bitová pole většinou nevedou k ušetření paměti (více instrukcí,...)

19 Bitová pole bitový součin - & 77 & 198 = & = Operandy operátoru binárního součinu mohou být pouze výrazy celočíselného typu, není tedy možné provádět bitový součin s hodnotami typu float, double ani long double. #define liche(x) (1 & (x)) makro pro určení lichosti a sudosti bitový součet - | 77 | 198 = | = bitový exklusivní součet - ^ 77 ^ 198 = ^ = bitová negace - ~ Na rozdíl od předchozích operátorů je bitová negace unárním operátorem, tedy má pouze jeden operand. Ten musí být, stejně jako v předchozích případech, celočíselného typu. Při provádění operace jsou postupně všechny jeho bity negovány a takto získaná hodnota je výsledkem použití operátoru. V následujícím příkladu uvažujeme typy unsigned char. V případě použití typu signed by ještě hrál roli negovaný znaménkový bit.

20 Bitová pole ~77 = Protože jsou negovány všechny bity čísla, včetně počátečních nul, znamená to, že pro operandy se stejnou hodnotou, ale různým typem (char, short, int, long int), bude výsledná hodnota různá. bitový posun doleva - << Při posunu se bity nejvíce nalevo ztrácejí a zprava jsou uvolněná místa doplněna nulami. Následující příkaz vrátí o dvě místa bitově posunutou hodnotu čísla << 2; před posunem (hodnota 45) po posunu (hodnota 180, výsledek celého výrazu) Bitový posun doleva se často používá k provádění násobení mocninami dvou. Tento způsob je totiž znatelně rychlejší než normální násobení. Platí, že x << n = x*2 n. Schopnější překladače dnes již samy nahrazují obyčejné násobení bitovým posunem. bitový posun doprava - >> Komplementární operací k bitovému posunu doleva je bitový posun doprava. V tomto případě se bity zprava ztrácí a zleva jsou doplňovány nulou u neznaménkových typů, nebo znaménkovým bitem u typů znaménkových, což je ale implementačně závislé. Stejně jako se dal bitový posun doleva použít k násobení, lze zase bitový posun doprava použít k celočíselnému dělení mocninami dvou. x >> n = x/2 n 48 >> 4 = 3

21 Bitová pole - jde o zvláštní případ členu struktury, může být znamémkové, bezznaménkové, implicitní chápání bezznaménkovosti závisí na impementaci kompilátoru, je tedy lepší explicitně určit typ signed nebo unsigned - délka bitového pole může být 1 až 16 bitů, nevyužité bity zůstávají jako rezerva, nevztahuje se na ně zarovnávání na hranici slova - bitové pole může být pouze členem struktury, struktura s bitovým polem může obsahovat i členy běžného typu typ [identifikator] : sirka; typ - char, unsigned char, int, unsigned int identifikator - jméno pro skupinu bitů, pokud je vynechán, jsou bity rezervovány sirka - pocet bitů pro danou skupinu

22 Bitová pole - hodnoty jsou ukládány ve dvojkovém doplňkovém kódu s inter- pretací závislou na znaménkovosti struct POLE_BITU {Dosažitelnost prvků inti : 2;my_my.i = 1; unsigned j : 5;my_my.j = 23; int : 4;my_my.k = 0; intk : 1;my_my.m = -1; intm : 4; } my_my; mk nepoužito j i - používání bitových polí může přinášet problémy s portabilitou programů, detaily ukládání jsou implementačně závislé - nelze získat adresu bitového pole

23 struct { unsigned KEYWORD : 1; unsigned EXTERNAL : 1; unsigned STATIC : 1; } flags; flags.EXTERN = flags.STATIC = 1;/* nastavení bitů */ flags.EXTERN = flags.STATIC = 0;/* vynulování bitů*/ if(flags.EXTERN == 0 && flags.STATIC == 0).../* testování */ #define KEYWORD01 #define EXTERNAL02 #define STATIC flags |= EXTERNAL | STATIC; /* nastaví bity EXTERNAL a STATIC */ flags &= ~(EXTERNAL | STATIC); /* vynuluje bity EXTERNAL a STATIC */ if((flags & (EXTERNAL | STATIC)) == 0 … /* splněná podmínka pro vynulované */ Bitová pole

24 Uniony - union je datový typ, který má několik prvků různých typů, ale programátor může používat vždy jen jeden z nich, tyto prvky leží v paměti na jednom místě, velikost unionu odpovídá velikosti největšího prvku - union šetří místo v paměti, pokud programátor ví, že bude potřebovat pouze jeden prvek, ale neví, jakého typu, při nepovinné inicializaci uvádíme ve {} hodnotu příslušnou prvnímu typu - přístup k prvkům unionu, operace s uniony jsou stejné jako u struktur, uniony mohou být součástí polí a struktur a opačně union jmeno { int ival; float fval; char *pval; } a; - pokud chceme šablonu použít později: union jmeno

25 Uniony - sjednocení, slouží k ukládání složek různého datového typu na jedno místo paměti, složky netvoří celou proměnnou, v jednom okamžiku je proměnná tvořena vždy jedním ze členů. K jednomu paměťovému místu tak lze přistupovat různým způsobem struktura: char + int + float = 7 B union: char + int + float = 4 B - deklarace unionu má tvar: union jmenovka { } promenna; - význam jednotlivých deklarátorů je shodný se strukturami

26 Uniony - bitové pole už smí být členem unionu, všechny členy unionu se ukládají od stejné adresy a překrývají se, velikost unionu je tedy dána velikostí největší složky - opět není povoleno vkládání unionů stejného typu do sebe, opět se řeší pomocí směrníku promenna_union.slozka smernik_union -> slozka union znamenko { long znam;/* 4 B, n.znam */ unsigned long bez_znam;/* 4 B, n.bez_znam */ } n; struct { char jmeno[30]; enum {muz, zena} pohlavi; union { enum {ne, ano} vojak;/* zamestnanec.zdata.vojak */ char rozena[20]; } zdata;/* zamestnanec.zdata.rozena */ } zamestnanec;

27 Uniony

28 - použití unionu pro simulaci registrů procesoru (DOS.H) struct BYTEREGS { unsigned char al, ah, bl, bh; unsigned char cl, ch, dl, dh; }; struct WORDREGS { unsigned int ax, bx, cx, dx; unsigned int si, di, cflag, flags; }; union REGS { struct WORDREGS x; struct BYTEREGS h; }; void main(void) { union REGS TAMARA; ….. TAMARA.h.al = 0x34; TAMARA.h.ah = 0x12; printf(“0x%x”, TAMARA.x.ax);/* vytiskne se 0x1234 */ }

29 Adresa struktury: 913E:0004 Hodnota y: 11 Adresa struktury: 913E:0008 Hodnota y: Adresa struktury: 913E:0004 Hodnota y: 11 Adresa struktury: 913E:0000 Hodnota y: Hodnota y: 12 Hodnota y: 15 struct TEST { int x; int y; } *p, *p1; p=(struct TEST*)calloc(1, sizeof(struct TEST)); p1=p; p->x=22; p->y=11; printf("\nAdresa struktury: %p", p); printf("\nHodnota y: %d", p->y); p++->y; printf("\nAdresa struktury: %p", p); printf("\nHodnota y: %d", p->y); p=p1; printf("\nAdresa struktury: %p", p); printf("\nHodnota y: %d", p->y); (--p)->y; printf("\nAdresa struktury: %p", p); printf("\nHodnota y: %d", p->y); p=p1; p->y++; printf("\nHodnota y: %d", (p->y)++); (p->y)++; printf("\nHodnota y: %d", ++(p->y));


Stáhnout ppt "7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole - uniony (sjednocení) Studijní materiály najdete na adrese:"

Podobné prezentace


Reklamy Google