+ All Categories
Home > Documents > 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

Date post: 11-Jan-2016
Category:
Upload: wilbur
View: 29 times
Download: 0 times
Share this document with a friend
Description:
7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole - uniony (sjednocení) Studijní materiály najdete na adrese: http://www.uai.fme.vutbr.cz/~vdumek/. Struktury. struct {struct STRU { int k1, k2;float h, z; char *buf1;char pole[10]; - PowerPoint PPT Presentation Copyright Complaint Adult Content Flag as Inappropriate Report This Download Presentation 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - Presentation Transcript 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole - uniony (sjednocení) Studijní materiály najdete na adrese: http://www.uai.fme.vutbr.cz/~vdumek/ Struktury 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 };
29
7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole - uniony (sjednocení) Studijní materiály najdete na adrese: http://www.uai.fme.vutbr.cz/~vdumek/
Transcript
Page 1: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

7. přednáška20. 3. 2008

- práce se strukturami- bitové operace- bitová pole- uniony (sjednocení)

Studijní materiály najdete na adrese:

http://www.uai.fme.vutbr.cz/~vdumek/

Page 2: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

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

Page 3: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

struct { int a, b; char *c; int pole[5]; double d;} upoc = { 1, 2, “TEXT”, {1, 3, 5, 7, 9}, 3.141312 };

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

Page 4: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

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;

Page 5: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

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)

Page 6: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

- 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 { ….. …… struct TADY a; struct TADY *a; …… ……. }; };

NE ANO

Práce se strukturami

Page 7: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

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));

Page 8: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

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;

Page 9: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

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

Page 10: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

Práce se strukturami

Page 11: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

Práce se strukturamistruct 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

Page 12: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

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

Page 13: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

*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 yp++->x inkrementuje 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;

Page 14: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole
Page 15: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

#include <stdio.h> #include <string.h> #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, 123.99}; cislo.re = 12.3456; cislo.im = -987.654; polozky[0].ev_cislo = 0; strcpy(polozky[0].nazev, "polozka cislo 0"); polozky[0].na_sklade = 20; polozky[0].cena = 45.15;

Page 16: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

ppolozky = polozky + 1; ppolozky->ev_cislo = 1; /* (*ppolozky).ev_cislo = 1; */ strcpy(ppolozky->nazev, "polozka cislo 1"); ppolozky->na_sklade = 123; ppolozky->cena = 9945.15; 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 = 0.00000 im = 1.00000 re = 12.34560 im = -987.65399 cislo: 8765 pocet: 100 cena: 123.99 nazev:nazev zbozi na sklade cislo: 0 pocet: 20 cena: 45.15 nazev:polozka cislo 0 cislo: 1 pocet: 123 cena: 9945.15 nazev:polozka cislo 1

Page 17: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

Bitové operace

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

Page 18: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

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 intdeklarace 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 slovobitové pole musí být typu int, signed int nebo unsigned intjednotlivé proměnné uvnitř bitového pole nemají své adresybitová pole většinou nevedou k ušetření paměti (více instrukcí, ...)

Page 19: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

Bitová pole

bitový součin - &77 & 198 = 681001101 & 11000110 = 01000100 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 = 207 1001101 | 11000110 = 11001111 bitový exklusivní součet - ^77 ^ 198 = 139 1001101 ^ 11000110 = 10001011 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.

Page 20: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

Bitová pole

~77 = 178 01001101 10110010 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 45. 45 << 2; před posunem (hodnota 45) 00101101po posunu (hodnota 180, výsledek celého výrazu) 10110100 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*2n. 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/2n 48 >> 4 = 3

Page 21: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

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 intidentifikator - jméno pro skupinu bitů, pokud je vynechán, jsou bity rezervoványsirka - pocet bitů pro danou skupinu

Page 22: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

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ů int i : 2; my_my.i = 1; unsigned j : 5; my_my.j = 23; int : 4; my_my.k = 0; int k : 1; my_my.m = -1;

int m : 4; } my_my;

15 14 13 12 11 3410 69 8 7 5 2 1

1 1 1 1 1 1 1 1 1

0

000 - - - -

-1 0 -- 23 1

m k 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

Page 23: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

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 KEYWORD 01#define EXTERNAL 02#define STATIC 04...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

Page 24: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

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

Page 25: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

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 {<seznam slozek> } promenna;

- význam jednotlivých deklarátorů je shodný se strukturami

Page 26: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

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.slozkasmernik_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;

Page 27: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

Uniony

Page 28: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

Uniony- 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 */}

Page 29: 7. přednáška 20. 3. 2008 - práce se strukturami - bitové operace - bitová pole

Adresa struktury: 913E:0004Hodnota y: 11Adresa struktury: 913E:0008Hodnota y: 28531Adresa struktury: 913E:0004Hodnota y: 11Adresa struktury: 913E:0000Hodnota y: -28387Hodnota y: 12Hodnota 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));


Recommended