Štruktúry (jazyk C)
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
- K položkám štruktúry pristupujeme pomocou operátora bodka ´.´
- Pre prácu s položkami štruktúry platia rovnaké pravidlá ako s premennými danej položky
- V našom príklade je d.den a d.rok dátový typ int
- 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:
0 | 1 |
1 | 2 |
2 | 3 |
Matica B bude mať hodnoty:
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ú