Struktura, union a výčet v jazyce C

08-Struktura, union a výčet

Struktura

Struktura není nic jiného než soubor proměnných které mají nějakou logickou souvislost a lze je jako celek nějak použít.

Název datového typu struktury se píše velkými písmeny!

typedef struct muj //nazev struktury
   {
   }MUJ; //název datového typu
x.a = 10;
strcpy(x.b,"Ahoj");

MUJ x, *z;
z = (MUJ*)malloc(sizeof(MUJ))

V haldě se vytvořila struktura z s částí a a b, přístup do ní (vnořeně) (*z).a (tečka má větší prioritu)
(šikpa na haldu, tečka na zásobník) z->a=15;
Do struktury do funkce posíláme jen adresu, přes '->', přístup pomocí *.

1. Struktura není pojmenována, nedá se využít dále v programu, lze používat pouze definované proměnné:

struct {
        int vyska; 
        float vaha;
       } pavel, honza, karel;

2. Struktura je pojmenována, dá se využít dále v programu

struct miry { 
             int vyska;
             float vaha;
            } pavel, honza, karel;
struct miry jan, martin; // definice proměnných
       miry jan, martin; // chyba

3. Definice struktury jako nový datový typ pomocí příkazu typedef, k definici proměnných není potřeba klíčové slovo struct

typedef struct {
                int vyska;
                float vaha;
               } MIRY;
MIRY pavel, honza, karel;

4. definice pomocí typedef, kdy je struktura pojmenována, používá se, když struktura odkazuje na sebe sama

typedef struct polozka {
                        int hodnota;
                        struct položka *dalsi;
                       } POLOZKA;

Použití

1. Přístup k prvkům pomocí tečkové notace

pavel.vyska = 186;

2. Pole struktur

MIRY lide[100]; 
lide[50].vyska = 176;

3. Je možné pracovat s celou strukturou najednou (honza = pavel – kopie celé struktury najednou)
4. Pole ve struktuře

typedef struct { 
                int pole[10];
               } STR_POLE;
STR_POLE x; 
x.pole[1] = 5;

5. Pointer na strukturu

MIRY *clovek; 
clovek = (MIRY*) malloc(sizeof(MIRY));

6. Přístup k dynamické struktuře

(*clovek).vaha = 70.4; // nebo jednodušeji  
  clovek->vaha = 70.4; 

7. Inicializace struktury

MIRY a = {190, 84.3};
TSTRUKT pole[5];
 //pole 5ti prvků, každý prvek má své položky
main: pole[1].cislo=15;

Když posílám pole do fce, posílám tam jenom adresu. Mám to uloženo v pointeru.
fce:

p[1].cislo=25;

Struktura ve struktuře, přístup přes tečky

p[0].datum.rok=2012;

Union

Protože se jednotlivé prvky unionu překrývají, je jasné, že po přiřazení hodnoty některému z nich se dá pracovat již pouze s tímto prvkem, a to až do doby, kdy dojde k novému přiřazení. V opačném případě bychom pracovali s „deformovanými“ daty (i když i tato vlastnost se dá v některých případech patřičně využít). Zde se projeví nevýhoda unionů, které neuchovávají informaci o tom, který jejich prvek je právě využíván. Možností, jak toto obejít, je zabalit union do další struktury obsahující navíc položku s informací (např. číselnou) o právě používaném prvku unionu:

Zjistí, které je větší a/b a vyalokuje jen to větší.
Union si dělá místo pro největší položku, jednotlivé položky se přepisují. Přístup přes tečku.

typedef union {
               char c;
               int i;
               float f;
              } TEST;

Výčet

Jednoduchý celočíselný

Jedná se vlastně o jakousi náhradu za symbolické konstanty vytvářené pomocí makra #define. Uživatel si pro nový výčtový typ sám definuje množinu přípustných hodnot uvedením všech jejich prvků. Není tedy problém vytvořit si pomocí enum nový typ, jež může nabývat například hodnot CERVENA, MODRA, ZELENA.
Vnitřně jsou pak tyto konstanty reprezentovány celými čísly, a to nejmenšího znaménkového typu, který je schopen všechny prvky nového typu obsáhnout.

Slouží k definici seznamu symbolických konstant, které jsou většinou vzájemně závislé.

typedef enum {
              MODRA, CERVENA, ZELENA, ZLUTA
             } BARVY;
BARVY x = MODRA;

Čísluje se implicitně od nuly, lze explicitně inicializovat:

typedef enum {
              MODRA = 5, CERVENA = 8, ZELENA, ZLUTA = 15      
             } BARVY;  // ZELENA bude mít číslo 9
typedef enum 
 {
  raz, dva, tri
 } POCTY;

POCTY a;

můj název pro 0 je raz
Nemůžu řetězec načíst "dva" a nemůžu jej tak vypsat, není to řetězec! //souvislost s barvami webových stránek