You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 6 Next »

Ciele cvičenia

Cvičenie je zamerané na prácu so štruktúrovaným údajovým typom resp. štruktúrou (struct). 

Po osvojení si učiva, si študent dokáže používať štruktúrovaný údajový typ, dokáže ho definovať a inicializovať. Študent dokáže pristupovať k v štruktúre uloženým údajom a meniť ich. Pristupovať k údajom dokáže priamo alebo prostredníctvom smerníkov.  Ďalej si študent po osvojení si učiva prehĺbi vedomosti a zručnosti s prácou so smerníkom a pamäťou, dokáže dynamicky alokovať pamäť pre štruktúru, resp. vlastný údajový typ.

  • Štruktúrovaný údajový typ - Štruktúry v jazyku C
  • Definícia vlastného údajového typu
  • Dynamická alokácia pamäte a smerník na štruktúru

Odporúčaná literatúra a dôležité odkazy

[1] KPI-FEI-TUKE:  Prednáška č. 3 - Structures

[2] KPI-FEI-TUKE:  Cvičenie č. 6 - Complex Numbers

[3] Tutorialspoint: 



Štruktúrovaný údajový typ

Štruktúra v jazyku C je údajový typ, ktorý môže uložiť do jednej premennej ale tento vo svojom vnútri obsahuje niekoľko prvkov. Tieto prvky ale na rozdiel od polí (1R, 2R...) nemusia byť rovnakého údajového typu. Štruktúra nám teda umožňuje vytvárať premenné, ktoré môžu reprezentovať entity s veľkým množstvom parametrov. Pod pojmom entita si pre potreby výkladu tohto učiva môžeme predstaviť napríklad auto. Každému je zrejmé, že keď sa bavíme o aute môžeme sa rozprávať o mnohých atribútoch (Značka, Model, Rok výroby, Palivo, Farba, ...).  Áno, všetky tieto parametre by bolo možné ukladať do separátnych premenných a následne mať systém, ktorý by jednoznačne determinoval, ktorý údaj patrí k danému vozidlu (niečo ako sql databáza). V C-čku ale pre prácu môžeme využiť údajový typ štruktúra, ktorú môžeme nazvať AUTO a jednotlivé vozidla vozového parku budú reprezentované ako samostatné entity s vlastnými parametrami. 

V nasledujúcom príklade si ukážeme ako štruktúru zadefinovať a inicializovať. Existuje niekoľko spôsobov ako to urobiť. Vždy však štruktúru definujeme buď pred funkciou main alebo vo vlastnom hlavičkovom súbore.  Definícia môže vyzerať nasledovne:

Definícia

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Tu je definovaná štruktúra. Vidíme, že táto štruktúra obsahuje rôzne údajové typy (reťazce, čísla, znaky). 
struct Auto {
              char Znacka[10];
              char Model[10];
              int Rok;
              char Palivo;
              char Farba[10];
            };

int main()
{ // Tu pokračuje funkcia main .... 

Vidíme, že v predošlom bloku kódu sme zatiaľ iba zadefinovali aké atribúty jednotlivé autá budú mať. Ak chceme vytvoriť entitu napr. auto_1 resp. auto_2 ... , ktorá bude mať atribúty štruktúry Auto, tak to môžeme spraviť viacerými spôsobmi. V nasledujúcom kóde sú tieto zobrazené. Pozor, takto sa robí inicializácia premennej a môže sa v kóde urobiť iba raz!

Inicializácia

// Tu boli hlavičky a definícia štruktúry Auto
int main()
{   // 1. spôsob - Atribúty sú uvedené v takom poradí ako je definovaná štruktúra.
	// V takom prípade stačí ak sú uvedené iba hodnoty týchto atribútov.
	struct Auto auto_1 = { "Skoda", "Favorit", 1989, 'B', "Modra"};
	
	// 2. spôsob - Atrubúty nastavujeme v ľubovolnom poradí, vtedy používame takzvané - Designated initialisers
    struct Auto auto_2 = {
                          .Znacka = "Peugeot",
                          .Model  = "307",
                          .Farba  = "Strieborna",
                          .Rok    = 2004,
                          .Palivo = 'D',
                         };
 // Tu pokračuje funkcia main ....

K jednotlivým prvkom štruktúry pristupujeme cez operátor bodky "." (v prípade ak nepoužívame smerníky!)  Nasledujúci kód zobrazuje priradenie parametrov ďalšiemu vozidlu auto_3, ktorého parametre neboli vopred inicializované. Týmto spôsobom môžeme meniť aj atribúty skôr inicializovaných vozidiel (auto_1 a auto_2). V nasledujúcom kóde sú aj vypísané atribúty jednotlivých vozidiel.

// Tu boli hlavičky a definícia štruktúry Auto
int main()
{   
	struct Auto auto_1 = { "Skoda", "Favorit", 1989, 'B', "Modra"};
    struct Auto auto_2 = {
                          .Znacka = "Peugeot",
                          .Model  = "307",
                          .Farba  = "Strieborna",
                          .Rok    = 2004,
                          .Palivo = 'D',
                         };
  struct Auto auto_3; // Iba deklarácia, bez inicializácie.
  // Platí to čo už vieme zo ZAP a predošlých hodín PROG. Reťazce musíme 
  // skopírovať cez strcpy(). 
  strcpy(auto_3.Znacka,"Citroen");
  strcpy(auto_3.Model,"Saxo");                    
  strcpy(auto_3.Farba,"Zlta");    
  auto_3.Rok = 2001;
  auto_3.Palivo = 'B';

printf("\n---------------------------------------\n");   
 printf("Znacka >> %s\n", auto_1.Znacka);
 printf("Model  >> %s\n", auto_1.Model);
 printf("Rok    >> %d\n", auto_1.Rok);
 printf("Palivo >> %c\n", auto_1.Palivo);
 printf("Farba  >> %s\n", auto_1.Farba); 
 printf("---------------------------------------\n");   

 printf("Znacka >> %s\n", auto_2.Znacka);
 printf("Model  >> %s\n", auto_2.Model);
 printf("Rok    >> %d\n", auto_2.Rok);
 printf("Palivo >> %c\n", auto_2.Palivo);
 printf("Farba  >> %s\n", auto_2.Farba); 
 printf("---------------------------------------\n"); 

 printf("Znacka >> %s\n", auto_3.Znacka);
 printf("Model  >> %s\n", auto_3.Model);
 printf("Rok    >> %d\n", auto_3.Rok);
 printf("Palivo >> %c\n", auto_3.Palivo);
 printf("Farba  >> %s\n", auto_3.Farba); 
 printf("---------------------------------------\n"); 
ab123cd@zapfei:dir$ gcc -Werror -Wall auta.c -lm -o AUTA
ab123cd@zapfei:dir$ ./AUTA

---------------------------------------
Znacka >> Skoda
Model  >> Favorit
Rok    >> 1989
Palivo >> B
Farba  >> Modra
---------------------------------------
Znacka >> Peugeot
Model  >> 307
Rok    >> 2004
Palivo >> D
Farba  >> Cervena
---------------------------------------
Znacka >> Citroen
Model  >> Saxo
Rok    >> 2001
Palivo >> B
Farba  >> Zlta
---------------------------------------

Môžeme si všimnúť, že takýto prístup k vytváraniu jednotlivých vozidiel vozového parku je dosť "neohrabaný". Vhodnejšie by bolo ak by jednotlivé autá boli položkami 1R poľa, ktoré by využívalo štruktúru. Toto si ukážeme v nasledujúcom texte,


Ak spracovávame veľké množstvo dát (napr. databázu áut na predajni) je možné tieto mať uložené v 1R poli. Toto môžeme urobiť nasledovne: Výpis bude identický s tým, ktorý bol v predchádzajúcom príklade.

// Tu boli hlavičky a definícia štruktúry Auto
int main()
{
  // Vidíme, že štruktúra Auto je teraz 1R poľom, v ktorom sú alokované tri položky. 
  struct Auto auto_1R[3];
  
  strcpy(auto_1R[0].Znacka,"Skoda");
  strcpy(auto_1R[0].Model,"Favorit");                    
  strcpy(auto_1R[0].Farba,"Modra");    
  auto_1R[0].Rok = 1989;
  auto_1R[0].Palivo = 'B';
  
  strcpy(auto_1R[1].Znacka,"Peugeot");
  strcpy(auto_1R[1].Model,"307");                    
  strcpy(auto_1R[1].Farba,"Cervena");    
  auto_1R[1].Rok = 2004;
  auto_1R[1].Palivo = 'D';
  
  strcpy(auto_1R[2].Znacka,"Citroen");
  strcpy(auto_1R[2].Model,"Saxo");                    
  strcpy(auto_1R[2].Farba,"Zlta");    
  auto_1R[2].Rok = 2001;
  auto_1R[2].Palivo = 'B';
  
  printf("\n---------------------------------------\n"); 
  for(int i=0; i<3; i++)
  {
     printf("Znacka >> %s\n", auto_1R[i].Znacka);
     printf("Model  >> %s\n", auto_1R[i].Model);
     printf("Rok    >> %d\n", auto_1R[i].Rok);
     printf("Palivo >> %c\n", auto_1R[i].Palivo);
     printf("Farba  >> %s\n", auto_1R[i].Farba); 
     printf("---------------------------------------\n");   
   }    
  
 return 0;
}

Vlastný údajový typ

V literatúre sa pri práci so štruktúrou veľmi často stretávame s tým, že štruktúra je definovaná ako vlastný údajový typ. Toto je pomerne výhodné, nakoľko potom nie je potrebné písať struct zakaždým, keď sa deklaruje nový prvok (napr. struct Auto auto_3;) Vlastný údajový typ zadefinujeme pomocou príkazu typedef. Pokračujme s príkladom, ktorý sme používali doteraz ale tak, že si zadefinujeme vlastný údajový typ AUTO. Celý kód je zobrazený nižšie. Môžeme si všimnúť, že sa zmenil iba spôsob definície štruktúry, kedy sa pred struct napísal príkaz typedef a názov vytvorenej premennej sa zapísal za štruktúru. Vo funkcii main sa následne premenná auto_1R deklarovala ako údajový typ AUTO.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct  {
              char Znacka[10];
              char Model[10];
              int Rok;
              char Palivo;
              char Farba[10];
            } AUTO; 

int main()
{
  AUTO auto_1R[3];

  strcpy(auto_1R[0].Znacka,"Skoda");
  strcpy(auto_1R[0].Model,"Favorit");                    
  strcpy(auto_1R[0].Farba,"Modra");    
  auto_1R[0].Rok = 1989;
  auto_1R[0].Palivo = 'B';
  
  strcpy(auto_1R[1].Znacka,"Peugeot");
  strcpy(auto_1R[1].Model,"307");                    
  strcpy(auto_1R[1].Farba,"Cervena");    
  auto_1R[1].Rok = 2004;
  auto_1R[1].Palivo = 'D';
  
  strcpy(auto_1R[2].Znacka,"Citroen");
  strcpy(auto_1R[2].Model,"Saxo");                    
  strcpy(auto_1R[2].Farba,"Zlta");    
  auto_1R[2].Rok = 2001;
  auto_1R[2].Palivo = 'B';
  
  printf("\n---------------------------------------\n"); 
  for(int i=0; i<3; i++)
  {
     printf("Znacka >> %s\n", auto_1R[i].Znacka);
     printf("Model  >> %s\n", auto_1R[i].Model);
     printf("Rok    >> %d\n", auto_1R[i].Rok);
     printf("Palivo >> %c\n", auto_1R[i].Palivo);
     printf("Farba  >> %s\n", auto_1R[i].Farba); 
     printf("---------------------------------------\n");   
   }    
  
 return 0;
}




  • No labels