Štruktúry (jazyk C)

Z Kiwiki
(Presmerované z Štruktúry jazyk C)
Skočit na navigaci Skočit na vyhledávání
Imbox draft.png
Toto je projekt, na ktorom sa ešte stále pracuje!!

Aj keď sú v tomto dokumente použiteľné informácie, ešte nie je dokončený. Svoje návrhy môžete vyjadriť v diskusii o tejto stránke.

Practice.png
Praktické príklady

Riešené príklady k tejto téme sú na stránke Štruktúry (riešené príklady)

Definícia štruktúr

Štruktúry majú v jazyku C význam dátových kontainerov, ktoré obsahujú pomenované položky ľubovoľného dátového typu. Štruktúry sú podobné dátovému typu záznam (record) v jazyku Pascal. Položky štruktúry sú uložené postupne v pamäti v poradí, ako boli zadefinované. Veľkosť štruktúry je totožná súčtu veľkostí všetkých jej premenných.

Príklad definície štrutúry:

1 struct datum
2 {
3     int   den;
4     char  mesiac[8];
5     int rok;
6 };


Vysvetlenie:

Riadok č. 1 - definícia štruktúry s názvom "datum". den a rok sú celočíselné typy (riadok č. 3 a 5), mesiac je reťazec (riadok č. 4). Definícia štruktúry musí byť uzatvorená v zložených zátvorkách '{' a '}' a za ukončujúcou zátvorkou je bodkočiarka ';'.

Použitie štruktúry a prístup k jej položkám

datum d; // d je premenná typu datum
d.den=1;
strcpy(d.mesiac,"januar");
d.rok=2010;

Pravidlá pre prácu s položkami štruktúry

  1. K položkám štruktúry pristupujeme pomocou operátora bodka ´.´
  2. Pre prácu s položkami štruktúry platia rovnaké pravidlá ako s premennými danej položky
    1. V našom príklade je d.den a d.rok dátový typ int
    2. d.mesiac je dátový typ jednorozmerné pole znakov.

Inicializácia

Položky štruktúry môžeme inicializovať pri vytváraní inštancie štruktúry. Ak štruktúru neinicializujeme, jej hodnoty zostanú tiež neinicializované (budú obsahovať náhodné hodnoty). Poradie inicializácie premenných štruktúry je rovnaké ako je poradie pri definícii. Nasledujúci kód vytvorí premennú d2 typu datum a inicializuje ho na "1. januar 2010". Tento kód robí urobí to isté ako v predchádzajúcom príklade.

datum d2={1,"januar",2010};

Hodnoty pri iniciaizácii musia zodpovedať dátovým typom štruktúry. V našom prípade musí byť ako prvá hodnota celé číslo, nasleduje pole znakov a akao posledný údaj je opäť celé číslo.

Práca s položkami štruktúry

Povolené operácie so štruktúrami

Prístup k položkám
d.den
Priradenie hodnôt položkám štruktúry
d.den=3
Pozor, pravidlá pre priradenie hodnôt pre dátový typ pole!
Priradenie rovnakých štruktúr
d2=d

Nepovolené operácie so štruktúrami

Porovnenie štruktúr
Štruktúry ako celok sa nedajú použiť v relačných výrazoch. Pri porovnávaní musíme pracovať s položkami štruktúry.

Vzorový príklad

Základná práca so štruktúrami

Zadanie: Vytvorte štruktúru, ktorá bude reprezentovať maticu. Matica je charakterizovaná počtom riadkov, počtom stĺpcov a samotným dátovou štruktúrou dvojrozmerné pole. Uvažujme max. rozmery 20x20.

Riešenie 1: Pre reprezenttáciu matice si vytvoríme 2rozmerné statické pole. Ako prvé si zadefinujeme štruktúru sMatica, ktorá nám bude reprezentovať našu maticu:

#define MAX 20
struct sMatica
{
   int r,s;
   int M[MAX][MAX];
};

V progmame použijeme túto štruktúru nasledovne:

int main()
{
  sMatica A,B;
  A.r=3;
  A.s=2;
  for(int i=0 ; i<A.r ; i++) 
    for(int j=0 ; j<A.s ; j++)
       A.M[i][j]=i+j;

  B.r=4;
  B.s=3;
  for(int i=0 ; i<B.r ; i++) 
    for(int j=0 ; j<B.s ; j++)
       B.M[i][j]=i*j;
}

Matici A sme nastavili rozmery 3x2, matici B rozmery 4x3. Pre prístup k položkám matice A použijeme zápis A.M. Tento výraz predstavuje dvojrozmerné pole celých čísel, preto musíme ešte špecifikovať index riadku a stĺpca. Matica A bude mať hodnoty:

Matica A
0 1
1 2
2 3

Matica B bude mať hodnoty:

Matica B
0 0 0
0 1 2
0 2 4
0 3 6

Štruktúry a funkcie

Úloha: vytvorte funkciu nacitajMaticu, ktorá načíta z klávesnice maticu. Pracujte s navrhnutou štruktúrou sMatica. Podobne vytvorte funciu vypisMaticu, ktorá bude danú maticu vypisovať. Riešenie: Vytvoríme finkciu nacitajMaticu s jedným parametrom typu sMatica. Funkcia bude bez návratovej hodnoty, ale parameter bude predávaný pomocou odkazu. Načítanie rozmerov matice bude mimo funkciu nacitajMaticu.

void nacitajMaticu(sMatica &X)
{
  for(int i=0 ; i<X.r ; i++) 
    for(int j=0 ; j<X.s ; j++)
       scanf("%d",&X.M[i][j]);
}

void vypisMaticu(sMatica &X) // & nie je nutný, ale použijeme ho kvôli efektivite
{
  for(int i=0 ; i<X.r ; i++) 
  {  for(int j=0 ; j<X.s ; j++)
       printf("%8d",X.M[i][j]);
     printf("\n");
  }
}

Použitie vo funkcii main:

int main()
{
  sMatica A,B;
  A.r=3;     A.s=2;
  B.r=4;     B.s=3;

  nacitajMaticu(A);
  nacitajMaticu(B);

  vypisMaticu(A);
  vypisMaticu(B);
}

Štruktúry a návratová hodnota funckie

Úloha: Vytvorte funkciu scitajMatice, ktorá sčíta 2 matice a vráti výsledok tohto súčtu. Funkcia nebude nič vypisovať, na predanie výsledku použite nácratovú hodnotu. Riešenie: Vytvoríme funckiu scitajMatice, ktorá bude mať 2 parametre: matice, ktoré chceme sčítať. Ako návratový typ funkcie zvolíme dátový typ sMatica, čo reprezentuje maticu.

sMatica scitajMatice(sMatica &X,sMatica &Y) // & nie je nutný, ale použijeme ho kvôli efektivite
{
  sMatica Z;  // keďže funkcia vracia dátový typ sMatica, musíme si vytvoriť premennú tohto typu. Z bude zároveň výsledok súčtu matíc.
              // Predpokladáme, že matice X a Y majú rovnaké rozmery.
  Z.r=X.r;    // rozmery výslednej matice budú rovnakú ako rozmery vstupných matíc
  Z.s=X.s;
  
  for(int i=0 ; i<Z.r ; i++) 
    for(int j=0 ; j<Z.s ; j++)
      Z.M[i][j]=X.M[i][j]+Y.M[i][j];  // súčet matíc
  return Z; // výsledná matica ako návratová hodnota.
}

Použitie vo funkcii main:

int main()
{
  sMatica A,B,C;
  A.r=2;
  A.s=3;
 
  B.r=4;
  B.s=3;
  nacitajMaticu(A);
  nacitajMaticu(B);
 
  C=scitajMatice(A,B);
  vypisMaticu(C);
}

Štruktúry a smerníky

V jazyku C je možné vytvárať smerník na ľubovoľný dátový typ. Môžeme teda vytvoriť smerník na náš dátový typ štruktúra. Majme definovaný dátový typ datum:

struct datum{
   int den,mesiac,rok;
};

Ďalej, vytvorme si premennú typu smerník na štruktúru datum (premenna d1) a alokujme pre neho v pamäti miesto:

  datum *d1
  d=new datum;

K položkám štruktúr budeme potom pristupovať nasledovne:

  d1->den=2;
  d1->mesiac=3;
  d1->rok=2010;

Vidíme, že operátor bodka (.) sa zmenil na operátor šípka (->).

Dynamicky vytvorené pole štruktúr

Úlohou je dynamicky vytvoriť pole štruktúr o veľkosti n. Opäť použijeme operátor new:

  int n=10;
  datum *d1=datum[n];
  for(int i=0;i<n;i++)
  {  d1[i].den=i+1;
     d1[i].mesiac=1; // januar
     d1[i].rok=2010;  
  }

V tomto prípade sme vytvorili pole štruktúr, preto sme pre prístup k položkám štruktúry použili prístupový operátor bodka (.).

Teraz vytvorme pole smerníkov na štruktúru datum.

  int n=10;
  datum **d1=new datum*[n]; // d1 je smerník na smerník na štruktúru datum, alebo pole smerníkov na štruktúru datum.
  for(int i=0;i<n;i++)	
  {  d1[i]=new datum; // alokácia miesta pre dátovú štruktúru datum

     d1[i]->den=i+1;
     d1[i]->mesiac=1; // januar
     d1[i]->rok=2010;  
  }

Na rozdiel od predchádzajpceho príkladu, kde sme vytvorili pole štruktúr datum, teraz sme vytvorili pole smerníkov na štruktúru datum. Pre tieto smetníky sme alokovali potrebné pamäťové miesto (preto namiesto operátora bodka (.) používame operátor šípka (->) ).

Smerníky a funkcie

Funkcie vracajúce smerník na premennú