Dátové objekty


Obsah tém. 

  1. Čo je to dátový objekt?
  2. Vlastnosti dátového objektu
  3. POLE
  4. Jedno rozmerné pole
  5. Príklady pre prácu s poľom
  6. Dvojrozmerné pole - matica
  7. Príklady pre prácu s maticou
  8. Štruktúry
  9. Príklady na štruktúry
  10. Operácie s dátovým objektom
  11. Úlohy pre zopakovanie
  12. Funkcie
  13. Rekurzivita funkcií

Čo je to dátový objekt

Dátový objekt je časť pamäte, ktorú program používa na ukladanie údajov. Charakteristickou vlastnosťou tohto objektu je umiestnenie, veľkosť, spôsob použitia, názov a konečne informačný obsah. Základnou činnosťou počítača je programová transformácia dátových objektov a to:

  • z miesta na miesto - prenos údajov (buď v rámci operačnej pamäte, ale aj externých zariadení HD, DVD,...)
  • z jedného typy na druhý typ - pretypovanie dátového objektu
  • jedného obsahu na iný obsah - zmena hodnoty 

Základné objekty s ktorými program, napísaný v jazyku C, narába sú premenné a konštanty Na ich pomenovanie sa používajú identifikátory. Používajú sa v algebraických a logických výrazoch ako symboly predstavujúce hodnoty.  Premenné sú dátové objekty so zmeniteľným obsahom (na priradenie hodnoty používame priraďovací výraz). Hodnota konštánt sa raz určí a potom už nemení. Proces, ktorý premenným prideľuje názvy a typové označenie sa nazýva deklarácia. Ak sa premennej vyhradí v pamäti priestor, prípadne sa aj nastaví počiatočná hodnota hovoríme o definícii premennej. 

Tretím dôležitým dátovým objektom sú  funkcie.  Zatiaľ čo funkcia v matematike predstavuje matematický výraz ktorý transformuje vstupné atribúty do výsledku tzv. funkčnej hodnoty, v C jazyku je "funkcia" program, ktorý spracúva hodnoty vstupných premenných a výsledok umiestňuje do výstupnej premennej. Tu tiež, tak ako v matematike, dochádza k transformácii vstupných hodnôt na výstupnú hodnotu. 

Funkcia sa deklaruje, podobne ako premenná, určením identifikátora výstupnej hodnoty a jej typu. Na rozdiel od premennej sa za identifikátorom názvu funkcie uvádza do malých okrúhlych zátvoriek umiestnená deklarácia vstupných premenných - formálne parametre - ktoré používa funkcia v programe (záleží na poradí). Deklarácia funkcie je ako každý príkaz ukončená bodkočiarkou.  

Definícia funkcie má inú úlohu ako definícia premennej. Formálne začína rovnako ako deklarácia funkcie, ale miesto bodkočiarky je na konci prilepený programový blok. Použitie názvu funkcie (t.j. identifikátor funkcie) vo výrazoch je podobné ako premenných a konštánt. Rozdiel medzi nimi spočíva v okrúhlych zátvorkách  za identifikátorom funkcie, v ktorých môžu ale nemusia (v prípade tkzv. prázdnej hodnoty - void) byť uvedené vstupné hodnoty atribútov funkcie. 

Názvy premenných aj funkcií majú vo výrazoch rovnaké použitie - predstavujú hodnoty identifikované ich identifikátormi. Dej ktorý je za tým, je však iný v prípade premennej a iný v prípade funkcie. Zatiaľ čo premenná poskytne svoju hodnotu hneď, lebo jej identifikátor určuje adresu umiestnenia hodnoty, funkcia predtým najprv spustí svoj program. Pri štarte sa hodnoty atribútov uvedených v malých okrúhlych zátvorkách skopírujú do formálnych premenných uvedených v deklarácii a program sa vykoná. Výsledok programu - funkčná hodnota - za zapíše na pozíciu, ktorú určuje identifikátor  funkcie. Ďalej to už prebieha ako s hociktorou inou dátovou premennou. 

Poznámka: Nie každá funkcia vracia funkčnú hodnotu a nie každá funkcia potrebuje uviesť parametre. Sú funkcie ktoré vykonávajú transformácie externých dát a alebo vykonáva činnosť ovládajúcu hardware. Príkazy ktoré ich spustia obsahujú len Identifikátor a za ním prázdne zátvorky ukončené bodkočiarkou. Návratová hodnota funkcie sa dá aj v týchto prípadoch použiť ako správa - číslo - identifikujúce stav ako funkcia - procedúra splnila úlohu ( 0 - úspech , hocičo iné číslo chyby). 

 

Vlastnosti dátového objektu

Dátový typ
Udáva vlastnosti údaja uloženého v dátovom objekte.

základné

  • int    celé čísla, pre údaj je vyčlenené jedno pole bajtov 
  • float, double    reálne číslo jednoduchej a dvojnásobnej presnosti, dve polia pre celú a pre desatinú časť
  • char    jeden bajt schopný uchovať jeden znak zo súboru znakov ( najčastejšie ASCII znakov)

Tabuľka č.1

Datový typ Počet bitov Význam
char, unsigned char, signed char 8 znak
short, unsigned short, signed short 16 krátke celé číslo
int, unsigned int, signed int 16 nebo 32 celé číslo
long, unsigned long, signed long 32 dlhé celé číslo
enum 8|16|32 výčtový typ
float 32 reálne číslo
double 64 reálne číslo s dvojnásobnou dĺžkou
long double 80 ešte dlhšie re.čí.
pointer 16|32 smerník

Pre bližšie určenie dĺžky celého čísla sa používajú kvalifikátory short a long. Kvalifikátor unsigned ( bez znamienka) pripúšťa len celé kladné čísla no dvojnásobnej dĺžky.
napr.:

    short    int x;
    long     int y;
    unsigned int z;

V jazyku C chýba typ logický (boolean). Tento je nahradený typom int, kde nulová hodnota je totožná s hodnotou (FALSE) a nenulová s hodnotou true (TRUE).
Výslednou hodnotou relačných operátorov v prípade true je jednotka.

odvodené

Odvodené dátové typy sú vždy zložené zo základných dátových typov alebo ich kombinácií.

  • pole            dátový objekt zložený z dátových objektov rovnakého dátového typu
  • štruktúra     dátový objekt zložený z dátových objektov rôzneho dátového typu
  • smerník      reprezentuje adresu daného objektu   

Veľkosť
Každý dátový objekt má určený dátový typ, ktorý má jednoznačne určenú svoju veľkosť ( udáva sa v Bajtoch)
Veľkosti dátových objektov:

  • celočíselné     
  • reálne            
  • znak              
  • logický           
  • pole                
  • štruktúra         
2B až 4B 
4B až 8B
1B
1bit
veľkosť poľa sa určí ak počet prvkov vynásobíme veľkosťou prvku
veľkosť štruktúry určíme ak sčítame veľkosti všetkých prvkov tvoriacich štruktúru

Pozn. Viac informácií o veľkosti jednotlivých dátových objektoch viď. tabuľka č.1

Adresa
Je to číslo prvej pamäťovej bunky, kde sa v operačnej pamäti začína dátový objekt. Adresa je celé kladné číslo a udáva sa v hexadecimálnej sústave

Obsah
Hodnota, ktorá sa do dátového objektu ukladá. Je to vždy číslo. Význam tohto čísla určuje dátový typ.

Obor hodnôt
Veľkosť operačnej pamäte je ohraničená preto aj dátové objekty majú svoje ohraničenie. Hovoríme tomu, že dátový objekt má svoj obor hodnôt.
napr.

Význam Zápis Veľkosť Obor hodnôt
celé číslo so znamienkom  int 2B {-32768,...,32767}
celé číslo bez znamienk unsigned int 2B  {0,...........65535}
znak so znamienkom signed char  1B {-128,...,127}
znak bez znamienka  unsigned char  1B {0,...........255}

Pozn. Viac informácií o obore hodnôt jednotlivých dátových objektoch viď. tabuľka č.1

Možnosť meniť obsah
Dátový objekt, ktorý mení svoj obsah počas behu programu nazývame premenná.
Dátový objekt, ktorý nemení svoj obsah počas behu programu nazývame konštanta.

Meno
Meno dátového objektu vyjadruje identifikátor. Názov by mal vyjadrovať použitie dátového objektu napr. obvod_stvorca alebo pocet_ziakov.

Rozsah platnosti
Dátový objekt, ktorý má platnosť v celom programe nazývame - globálny.
Dátový objekt, ktorý má platnosť len v určitej časti programu (napr. v prgramovom bloku funkcie) nazývame - lokálny.

POLE

Pole je dátový objekt zložený z dátových objektov, ktoré majú rovnaký dátový typ. Počet prvkov poľa sa určí pri deklarácií.

Jednorozmerné pole

Deklarácia poľa:

Deklarácia poľa je podobná deklarácií jednoduchej premennej s tím rozdielom že za meno premennej uvedieme v hranatých zátvorkách počet prvkov poľa.
 

    dátový_typ meno_poľa[rozmer];

  • dátový_typ určuje z akých prvkov bude pole zložené
  • meno_poľa tvorí identifikátor premennej typu pole
  • rozmer je počet prvkov z ktorých sa pole skladá. Je to kladné číslo.
napr.:
 
    float pole[15];

Čo vieme zistiť z deklarácie?

napr.:  

    int a[20];
  • deklarácia poľa 20 - tich celých čísel
  • rozmer poľa je 20 prvkov
  • veľkosť 1 prvku poľa 2B, teda veľkosť poľa 40B
  • index prvého prvku poľa je 0 a posledného 19
  • meno poľa je a, pole je typu int

Počet prvkov poľa sa určí pri deklarácií. Údaj o počte prvkov je možné v deklarácií vynechať ( ak je pole definované inde) alebo v definícií (kde inicializujeme všetky prvky).

           Inicializácia

Pri definícií je možné pole zároveň aj inicializovať. Vtom prípade nasleduje za menom poľa a hranatými zátvorkami znak rovnosti a za ním v zložených
zátvorkách hodnoty, ktoré sa majú priradiť jednotlivým prvkom. Prvkom, ktoré neinicializujeme sa automaticky priradí hodnota 0.
Ak nezadáme  údaj o rozmere poľa urči si ho prekladač na základe počtu prvkov.

float pole[3]={ 2.24, 5.26 };

je to isté ako:

float pole[0]=2.24;
float pole[1]=5.26;
float pole2]=0;

alebo

float pole[]={ 2.24, 5.26 };

je to isté ako:

float pole[2]={ 2.24, 5.26 };


        Práca s poľom

K jednotlivým prvkom poľa sa pristupuje pomocou indexov, ktoré sa zapisujú do hranatých zátvoriek za menom poľa. Samotný identifikátor poľa predstavuje adresu 0-tého prvku poľa t.j. začiatok poľa.
Index prvku poľa určuje jeho poradie, pričom index prvého prvku poľa je 0 a posledného je rozmer-1. Prvky poľa sú uložené v pamäti za sebou.

Prvkom v poli priradzujeme hodnoty dvoma spôsobmi a to buď v cykle napr. pomocou funkcie scanf alebo  priamo, vymenovaním jednotlivých hodnôt.
Tento spôsob si však vyžaduje poznať hodnoty vopred
napr.:    int    pole[10] = { 1,4,5,7,8,9,6,5,54,23}; pri tomto spôsobe nemusíme uvádzať počet prvkov poľa v hranatých zátvorkách

        Reťazce


Reťazec znakov je zvláštnym druhom polí. Sú zložené z prvkov typu char. Reťazcové konštanty zapisujeme ako postupnosť znakov uzavretých medzi úvodzovkami.Reťazec je ukoncení znakom \0.

napr.: 

         char znak[10];

Inicializácia poľa prvkov typu char

         char znak[] = "skola";   

veľkosť tohto poľa je o 1 znak  väčšia ako počet znakov v reťazci, pretože každá reťazová konštanta je ukončená znakom \ 0

alebo

          char znak[] = {´s´,´k´,´o´,´l´,´a´,´\0´};

 

Príklady pre prácu s poľom

Príklad č.26:
Program, ktorý načíta z klávesnice n desatinných čísel a vypíše ich v obrátenom poradí a načítanom poradí. Kód \n pri vypisovaní znamená - prejdi na nový riadok.

#include<stdio.h>
#include<conio.h>

void main(void)      // void - znamená "žiaden typ - žiadna premenná"
{
   float pole[10]; //deklarácia poľa 10 reálnych čísel		
   int i,n;	  //i - premenná určujúca index prvku, n - premenná pre počet prvkov poľa 
   clrscr();     // zmaž obrazovku

   printf("\nZadaj počet prvkov pola:");
   scanf("%d",&n);	         // do premennej n sa uloží počet prvkov poľa
   for(i=0;i<n;i++)             //  načítanie n prvkov do poľa s indexom od i=0 až n-1
   {
      printf("\n      [%d] prvok pola: ",i);
      scanf("%f",&pole[i]);    // ulož načítaný údaj na pozíciu i-tého prvku poľa 
      }

   printf("\nČísla v obrátenom poradí.");
   for(i=n-1;i>=0;i--)			  // píš prvky v obrát.poradí, prvý vytlačený prvok 
   printf("\npole[%d]=%.2f",i,pole[i]);	  // má index i=n-1 a posledný i=0 s krokom i=i-1

   printf("\nČísla v načítanom poradí."); // čísla sú idexované podľa načítania 
                                          // prvé číslo i=0 a posledné i=n-1
   for(i=0;i<n;i++)	
   {
      printf("\npole[%d]=%.2f",i,pole[i]);// vytlačí index a obsah i-tého prvku z poľa
      }
   getch();
   }
Príklad č.27:
Program, ktorý načíta z klávesnice 7 celých čísel a vypíše na obrazovku súčet párnych a súčet nepárnych prvkov poľa.
 

#include<stdio.h>
#include<conio.h>

void main(void)         // funkcia nepoužíva parametre ani nevracia hodnotu
{
   int p=0,n=0,i,j,pole[10];   // pole 10 prvkov int

   clrscr();  //zmaž textovú obazovku

   printf("\nZadaj 7 celých čísel: \n");  // odriadkuje, vypíše text a odriadkuje

   for(i=0;i<7;i++)  // pre i rovne 1 až 6
   {
      printf("\n[%d] prvok pola: ",i);  //  
      scanf("%d",&pole[i]);   // &pole[i] je adresa prvku poľa i
      }

   for(j=0;j<7;j++)
   {
      if(pole[j]%2==0)   // operácia %2 mdulo 2 znamená - zvyšok po delení 2
         p=p+pole[j];    // ... bol 0 - párne číslo
      else
         n=n+pole[j];    // ... bol 1 - nepárne číslo
      }

   printf("\nSúčet parných prvkov poľa je %d.",p);
   printf("\nSúčet neparných prvkov poľa je %d.",n);

   getch();
   }

Príklad č.28:
Program, ktorý načíta z klávesnice 10 celých čísel a vypíše ich súčet.

#include<stdio.h>
#include<conio.h>

void main(void)
{
   int pole[10],i,s=0;

   clrscr();

   printf("\nZadaj 10 prvkov, ktoré chceš spočítať.\n");

   for(i=0;i<10;i++)
   {
      printf("\n[%d] prvok pola: ",i);
      scanf("%d",&pole[i]);
      }

   for(i=0;i<10;i++)
      s=s+pole[i];

   printf("\nSúčet prvkov poľa je %d.",s);

   getch();
   }

Príklad č.29:
Program, ktorý načíta z klávesnice n desatinných čísel a vypíše na obrazovku všetky s neparným indexom. 


#include<stdio.h>
#include<conio.h>

void main(void)
{
   float pole[10];
   int i;

   clrscr();
   printf("\nZadaj 10 desatinných čísel: \n");

   for(i=0;i<10;i++)
   {
      printf("\n[%d] prvok pola: ",i);
      scanf("%f",&pole[i]);
      }

   printf("\nTlačím prvky pola s neparným indexom:");   

   for(i=0;i<10;i++)
      if(i%2!=0)                     
         printf("\npole[%d]=%.2f",i,pole[i]);

   getch();
   } 

 

        Triedenie prvkov poľa

 

Tu bude teória

 

Príklad č.30:
Program, ktorý načíta z klávesnice n - celých čísel do poľa a podľa výberu ich zotriedi zostupne resp. vzostupne.

 

#include<stdio.h>
#include<conio.h>

void main(void)
{
   int a[100];		 //45,12,5,87,15,96,25,84,14,2};
   int i,x,j,pom,n,k;

   clrscr();
   printf("\nZadaj veľkosť poľa: ");
   scanf("%d",&n);
   for (i=0;i<n;i++)
   {
      printf("\n Zadaj a[%d]= ",i);
      scanf("%d",&a[i]); //&a[i] - adresa i-tého prvku poľa 
      }

   printf("\nChcete usporiadať prvky poľa zostupne alebo vzostupne (z/v): \n");
   x=getch();
   if(x=='v')
   {
      for (i=0;i<n-1;i++)    // pre n prvkov n krát zopakuj ...
      {
         for (j=0;j<n-i-1; j++)  //... triedenie postupne zmenšujúceho sa zvyšku
         {                       //v každom cykle 1 prvok umiestnime na pozíciu 
            if (a[j]>a[j+1])
            {
               pom=a[j];     // výmena dvoch prvkov poľa cez pomocnú premenú
               a[j]=a[j+1];
               a[j+1]=pom;
               }
            }
         }
      printf("\n Usporiadanie od najmenšieho po najväčší");
      for (i=0;i<n;i++)
         printf ("\na[%d]= %d",i,a[i]);
      }
   if(x=='z')
   {
      for (i=0;i<n-1;i++)
      {
         for (j=0;j<n-i-1;j++)
         {
            if (a[j]<a[j+1])
            {
               pom=a[j];    // výmena dvoch prvkov poľa cez pomocnú premenú
               a[j]=a[j+1];
               a[j+1]=pom;
               }
            }
         }
      printf("\n Usporiadanie od najväčšieho po najmenší");
      for (i=0;i<n;i++)
         printf ("\na[%d]= %d",i,a[i]);
      }

   getch();
   }

 

Úlohy

  1. Načítajte z klávesnice neurčitý počet celých čísel. Na obrazovke zobrazte všetky čísla s nepárnym indexom. Zadávanie čísel ukončíte číslom 0.
  2. Načítajte z klávesnice neurčitý počet celých čísel. Na obrazovke zobrazte všetky párne čísla aj s ich súčtom. Zadávanie čísel ukončíte číslom 0.
  3. Načítajte z klávesnice 10 desatinných čísel.
    • vypíšte ich v obrátenom poradí
    • vypíšte najmenší prvok poľa
    • utrieďte prvky od najmenšieho po najväčší
    • .vypíšte všetky prvky poľa s neparným indexom
  4. Načítajte z klávesnice n celých čísel.
    • vypíšte ich v načítanom poradí
    • utrieďte prvky od najväčšieho po najmenší
    • vypočítajte a vypíšte priemer nepárnych prvkov poľa
    • vypíšte súčet párnych prvkov

 

Viacrozmerné pole - matica

Viacrozmerné pole je vlastne jednorozmerné pole pričom jeho prvky tvoria opäť pole.
Klasickým príkladom dvojrozmerného poľa je matica.
Pod pojmom matica typu m * n chápeme obdĺžnikové pole, ktoré je zložené z m - riadkov a n - stĺpcov.

deklarácia matice:

dátový_typ meno_matice[m][n];

Prvky viacrozmerného poľa sa ukladajú v pamäti za sebou.
Na
príklad takto deklarované viacrozmerné pole

 matica matica[3][2];


má nasledovné usporiadanie prvkov v pamäti:

matica[0][0]
matica[
0][1]
matica[
1][0]
matica[
1][1]
matica[
2][0]
matica[
2][1]

Pri deklarácií viacrozmerného poľa môže prvá hranatá zátvorka prázdna.

Inicializácia

Viacrozmerné pole môžme inicializovať dvoma spôsobmi, ktorými dosiahneme to isté

Buď pre každú položku použijeme vlastný inicializačný systém, ktorý uzavrieme do zložených zátvoriek

int matica[ ][2] = {
                        {0,1},
                       
{1,1},
                        {2,2},
                       };

alebo každému prvku podľa poradia priradíme hodnotu

int matica[3][2] = {0, 0, 1, 1, 2, 2 }; 

 

Príklady pre prácu s maticou

Príklad č.31:
Program, ktorý načíta z klávesnice prvky matice a realizuje nasledujúce operácie:

  • výpis prvkov matice pomocou indexov
  • výpis prvkov matice priamo
  • výpis prvkov v 3. riadku matice

 

#include<stdio.h>
#include<conio.h>

void main(void)
{
   int matica[100][100];
   int s,r,i,j,min;

   clrscr();
   printf("Zadaj počet riadkov a stĺpcov\n");
   scanf("%d%d",&s,&r);

   for(i=0;i<s;i++)
   {
      for(j=0;j<r;j++)
      {
         printf("\nZadaj prvok M[%d,%d] = ",i,j);
         scanf("%d",&matica[i][j]);
         }
      }

   printf(" \n Výpis prvkov matice vo forme indexov\n");

   for(i=0;i<s;i++)
   {
      for(j=0;j<r;j++)
         printf("\nM[%d,%d] = %d ",i,j,matica[i][j]);
      }

   printf(" \n Výpis prvkov matice\n");

   for(i=0;i<s;i++)
   {
      printf("\n");
      for(j=0;j<r;j++)
      printf(" \t%d ",matica[i][j]);
      }

   printf("\nVýpis 3. riadku matice\n");

   for(j=0;j<r;j++)
      printf("\t%d ",matica[2][j]);

   getch();
   }

 

Štruktúry

Štruktúra je dátový objekt zložený z viacerých dátových objektov rôzneho dátového typu.

deklarácia štruktúry: 

    struct [menovka_štruktúry]
    {
       dátový_typ1 meno_prvku1;
       dátový_typ2 meno_prvku2;
       :
       dátový_typn meno_prvkun;
       } [premenná1, premenná2, ...]; 

Kľúčové slovo struct uvádza deklaráciu štruktúry, ktorá je zoznamom deklarácií uzavretých v zložených zátvorkách. Za kľúčovým slovom struct môže nasledovať nepovinný údaj, ktorý nazývame menovka štruktúry. Premenné uvedené v štruktúre sa nazývajú členy alebo položky štruktúry. Za pravou zloženou zátvorkou nasleduje buď bodkočiarka alebo zoznam identifikátorov premenných.

Príklad:
Vytvorme si štruktúru študent, ktorá bude v sebe obsahovať meno, priezvisko a počet vymeškaných hodín.

deklarácia našej štruktúry bude vyzerať takto:

   struct student 
   {
      char meno[20];
      char priezvisko [20];
      int hodiny;
      };

Zoznam identifikátorov uvádzame najmä vtedy, ak nepoužijeme pri deklarácii štruktúry jej menovku. Ak menovku použijeme, môžeme premenné uvedeného typu štruktúry definovať zvlášť s použitím menovky.

definícia štruktúry:

struct student jano;

Tým sme vytvorili premennú  jano, ktorá je typu student. Na hociktorú položku sa potom vieme odvolať nasledovne:

jano.meno    sprístupnenie položky meno
jano.priezvisko    sprístupnenie položky priezvisko

vo všeobecnosti

meno_premennej.meno_položky

Bodku medzi identifikátormi nazývame operátorom selekcie alebo kvalifikácie.
Externé alebo statické premenné typu štruktúry môžeme pri definícii súčastne aj inicializovať , napr.

struct student meno = {"jozef"};

Praktické je použiť štruktúru v poli. Jednoducho tak potom vieme vytvoriť napr. triedu, ktorá bude obsahovať 20 študentov s údajmi o nich

struct student trieda[20];

Príklady na štruktúry

Príklad č.32:
Program, ktorý načítava údaje o študentoch ( meno, priezvisko, vymeškané hodiny) do štruktúry a zobrazí ich na obrazovku.

#include<stdio.h>
#include<conio.h>

struct student                   // štrukturovaný dátový objekt
{
   char meno[20];
   char priezvisko[20];
   int hodiny;
   };

void main(void)
{
   struct student trieda[20];    // pole štrukturovaných prvkov
   int i, pocet;

   clrscr();

   printf("\nZadaj počet ziakov v triede: ");
   scanf("%d",&pocet);

   for (i=0;i<pocet;i++)
   {
      printf("Meno: ");
      scanf("%s",trieda[i].meno);  // string - reťazec má výnimku adresy t.j. bez &
      printf("Priezvisko: ");
      scanf("%s",trieda[i].priezvisko);
      printf("Vymeškane hodiny: ");
      scanf("%d",&trieda[i].hodiny);  // adresa položky i-teho prvku poľa
      }

   for (i=0;i<pocet;i++)
   {
      printf("\nMeno %d.študent je %s ",i+1,trieda[i].meno);
      printf("\nPriezvisko %d.študent je %s ",i+1,trieda[i].priezvisko);
      printf("\nVymeškané hodiny %d.študent sú %d ",i+1,trieda[i].hodiny); 
      }

   getch();
   }

 

Príklad č.33:
Program, ktorý načíta do štruktúry údaje o študentoch ( meno, priezvisko,  vymeškané hodiny a na obrazovku vypíše údaje o študentovi s maximálnym a minimálnym počtom vymeškaných hodín.

#include<stdio.h>
#include<conio.h>

struct student 
{
   char meno[20];
   char priezvisko[20];
   int hodiny;
   };

void main(void)
{
   struct student trieda[20];            // pole štrukturovaných prvkov
   int indexmin,indexmax,maxh,minh,i=0,j,k,n;

   clrscr();

   printf("\nKoľko študentov je v triede: ");
   scanf("%d",&n);

   for(i=0;i<n;i++)
   {
      printf("\nZadaj meno, priezvisko a počet vymeškaných hodín %d študenta:",i+1);
      scanf("%s%s%d",trieda[i].meno,trieda[i].priezvisko,&trieda[i].hodiny);
      }    // stringy %s(reťazce) majú výnimku pri adresovaní trieda[i].meno bez &

   maxh=trieda[0].hodiny;
   minh=trieda[0].hodiny;

   for(j=1;j<n;j++)
   {
      if (maxh<trieda[j].hodiny)
      {
         maxh=trieda[j].hodiny;
         indexmax=j;
         }
      }

   for(k=1;k<n;k++)
   {
      if (minh>trieda[k].hodiny)
      {
         minh=trieda[k].hodiny;
         indexmin=k;
         }
      }

   printf("\nŠtudent s najväčším počtom vymeškaných hodín: %s %s %d"\
                    ,trieda[indexmax].meno,trieda[indexmax].priezvisko,maxh);
   printf("\nŠtudent s najmenším počtom vymeškaných hodín: %s %s %d"\
                    ,trieda[indexmin].meno,trieda[indexmin].priezvisko,minh);
   getch();
   }

 

Príklad č. 34:
Program ktorý vytvorí databázu maximálne 20 kníh, pričom užívateľ si môže voliť počet kníh. Štruktúra kniha
bude obsahovať: meno a priezvisko autora, názov knihy, vydavateľstvo, typ knihy, atribút( vypožička-p, rezervovaná-r, voľná-v).
Po vytvorení databázy kníh, program umožňuje výpis informácii o knihách na základe výberu atribútu.
 

#include<stdio.h>
#include<conio.h>

struct kniha 
{
   char meno[40];
   char priezvisko[40];
   char nazov[20];
   char vydavatelstvo[10];
   int cena;
   int atributy;
   char typ[20];
   };

void main(void)
{
   struct kniha kniznica[20];    // pole 20 štruktúr
   int i, pocet;
   int znak;

   clrscr();

   printf("\nZadaj počet kníh: ");
   scanf("%d",&pocet);

   for (i=0; i< pocet;i++)
   {
      printf("\nNázov: ");            // stringy majú výnimky pri adresovaní
      scanf("%s",kniznica[i].nazov); // kniznica[i].nazov - adresa stringu
      printf("\nMeno autora: ");
      scanf("%s",kniznica[i].meno);
      printf("\nPriezvisko autora: ");
      scanf("%s",kniznica[i].priezvisko);
      printf("\nVydavateľstvo: ");
      scanf("%s",kniznica[i].vydavatelstvo);
      printf("\nCena knihy: ");
      scanf("%d",&kniznica[i].cena); // &kniznica[i].cena - adresa položky cena
      printf("\nAtribúty: ");
      kniznica[i].atributy=getch();
      putch(kniznica[i].atributy);
      printf("\n\nTyp knihy: ");
      scanf("%s",kniznica[i].typ);
      }

   printf("\nChcete vedieť info. o knihách s atribútom(\
                          voľná-v,\nrezervovaná-r, vypožička -p): ");
   znak=getch();

   for (i=0;i<pocet;i++)
   {
      if(znak==kniznica[i].atributy)
         printf("\n%s  %s  %s  %c  %s  ",\
                     kniznica[i].priezvisko,kniznica[i].meno,\
                     kniznica[i].nazov,\
                     kniznica[i].atributy,\
                     kniznica[i].typ);
      }

   getch();  // počkaj na stlačenie klávesnice
   }

 

Operácie s dátovým objektom

      definícia, deklarácia, inicializácia, priradenie

Definícia dátového objektu

  • určenie typu
  • určenie adresy
  • určenie mena
  • určenie obsahu

Deklarácia je len formálnou definíciou premennej bez nastavenia jej obsahu.
Inicializácia
určenie počiatočnej hodnoty dátového objektu už pri definícií.
Priradenie
znamená napĺňanie obsahu dátového objektu hodnotou napr.:  pocet_ziakov=4;

Všetky premenné sa pred použitím musia deklarovať. Deklarácia pozostáva zo špecifikácie typu a uvedenia zoznamu premenných tohto typu.
 

Príklad deklarácie jednoduchej premennej


    int  x, y, pocet;
    

Príklad deklarácie poľa


   char pole[10];

Príklad deklarácie štruktúry


  struct typOsoba 
   {
     char  meno[40];
     int   den;
     int   mesiac;
     int   rok;
     } osoba;
      

Posledným zápisom sme deklarovali štrukturovanú premennú osoba ( jej typ sme nazvali typOsoba). Táto premenná obsahuje štyri premenné, nazývané členy štruktúry inak aj položky. Prvá je pole 40 bajtov pre uloženie reťazca ASCII kódov ukončeného nulou (hodnotou 0 nie ASCII kódom 0 !), ktorá musí byť súčasťou reťazca (t.j. maximum znakov je 39). Nasledovné tri položky sú typu int. S premennou osoba sa narába ako s celkom. Môže sa zapisovať/čítať  do/z súboru ako jeden záznam (record). K položkám sa pristupuje s pomocou názvu štruktúry a mena položky takto:

   
   osoba->meno="Jano";

Deklaráciou sa určí, akého typu bude daná premenná.
Žiadnej z takto deklarovaných premenných sa ešte nepriradí hodnota, ale v pamäti sa jej rezervuje miesto, čiže sa jedná súčasne aj o definíciu

Jednoduchú premennú je možné zároveň aj inicializovať.
Inicializácia je
určenie počiatočnej hodnoty premennej už pri deklarácií.


   int x = 0;
   int a = ´0´;
   

Priradenie znamená napĺňanie obsahu dátového objektu hodnotou napr.:


   pocet_ziakov = 4;
   

Tu budem ešte doplňovať ...

Úlohy pre zopakovanie

  1. Načítajte z klávesnice 10 desatinných čísel.
        1. vypíšte ich v obrátenom poradí
        2. vypíšte najmenší prvok poľa
        3. utrieďte prvky od najmenšieho po najväčší
        4. vypíšte všetky prvky poľa s neparným indexom
  2. Načítajte z klávesnice neurčitý počet celých čísel vypíšte na obrazovku všetky párne čísla a ich súčet. Zadávanie čísel končí 0.
  3. Načítajte z klávesnice n celých čísel.
        1. vypíšte ich v načítanom poradí
        2. utrieďte prvky od najväčšieho po najmenší
        3. vypočítajte a vypíšte priemer nepárnych prvkov poľa
        4. vypíšte súčet párnych prvkov
  4. Načítajte z klávesnice neurčitý počet celých čísel
    vypíšte na obrazovku všetky čísla s nepárnym indexom. Zadávanie čísel končí 0.

     

Funkcie

Jazyk C umožňuje okrem používania knižničných funkcií aj vytváranie nových funkcií. Každý program napísaný v jazyku C musí obsahovať minimálne jednu funkciu nazvanú main. Vykonávanie programu začína aktiváciou funkcie main. Táto funkcia obsahuje buď príkazy celého programu, alebo ešte častejšie vyvoláva ďalšie funkcie deklarované vo funkcii main, tie môžu byť definované v danom programe (v zdrojovom texte) alebo v iných zdrojových súboroch. Užívateľom vytvorené funkcie môžu mať ľubovoľný názov, avšak aj tu existujú isté pravidlá. Názov funkcie musí začínať písmenom a obsahuje len zobraziteľné funkcie. Pre každú funkciu platí, že môže byť vo vnútri inej funkcie len deklarovaná. Môžeme vytvárať funkcie s parametrami, či bez parametrov, s návratovou hodnotou respektíve bez návratovej hodnoty. Jednotlivé možnosti si ukážeme postupne na jednotlivých príkladoch.

Deklarácia funkcie

Podáva prekladaču iba informácie o mene funkcie a type jej návratovej hodnoty. Tieto informáciu umožňujú prekladaču preložiť správne volanie funkcie z hľadiska prístupu k návratovej hodnote.

Definícia funkcie

dátový_typ meno_funkcie([vstupné parametre a ich dátové typy])
{
telo funkcie
}

Definícia funkcie pozostáva z  tového typu a identifikátora funkcie. Dátový typ udáva typ vracajúcej hodnoty funkcie. Ak je funkcia bez návratovej hodnoty tak udávame void??
V okrúhlych zátvorkách sa nachádzajú formálne parametre funkcie a im prislúchajúce dátové typy. Keďže pri definícií ešte nemôžme vedieť, s akými skutočnými parametrami bude funkcia narábať, sú to len formálne parametre. Tento údaj je nepovinný, závisí od toho či daná funkcia je bez parametrov alebo nie.
Ďalej nasleduje  telo funkcie, ktoré je uvedené v zložených zátvorkách. Telo funkcie je blok príkazov, ktoré sa majú pri definícií vykonať.

Spôsoby komunikácie medzi funkciami


pomocou parametrov (argumentov)
- využíva mechanizmus korešpondencie tzv. skutočných a formálnych parametrov - spôsob prenosu parametrov z miesta volania funkcie na miesto definície funkcie. V jazyku C sa parametre prenášajú iba hodnotou. To znamená, že v mieste volania sa zistí hodnota každého skutočného parametra a táto hodnota sa sprístupní funkcii. Funkcia teda pracuje s kópiami hodnôt skutočných parametrov.

pomocou globálnych premenných - využíva viditeľnosť globálnych premenných v rámci celého programu alebo v rámci jedného modulu (lokálne premenné).

pomocou návratovej hodnoty - riadiaci príkaz pre vykonanie návratu z funkcie je príkaz return (používajte dôsledne).

Najjednoduchšou užívateľom vytvorenou funkciou je funkcia bez parametrov a bez návratovej hodnoty.

Funkcia bez parametrov a bez návratovej hodnoty

Príklad č.34:

Program, ktorý pre troch žiakov načíta priezvisko žiaka a dve známky z ktorých vypočíta priemer s využitím vlastnej funkcie bez parametrov a bez návratovej hodnoty. Do vlastnej funkcie žiak nevstupujú žiadne parametre teda funkcia je bez parametrov.

#include < stdio.h>
#include < conio.h>

void ziak(void);                //deklarácia funkcie

void main(void)
{
   clrscr();
   ziak();			//volanie funkcie
   ziak();
   ziak();
   getch();
   }

void ziak (void)		//definícia funkcie
{
   float znamka1,znamka2,priemer;
   char priezvisko[20];		// premenná priezvisko je typu pole znakov

   printf("Zadaj priezvisko ziaka: ");	//načítanie údajov 
   scanf("%s",priezvisko);
   printf("Zadaj jeho dve znamky ");
   scanf("%f %f",&znamka1,&znamka2);
   priemer=(znamka1+znamka2) / 2;	//výpočet priemeru 
   printf("Priemer ziaka: %s je %.2f\n\n",priezvisko,priemer); //tlač výsledku
   }       // %.2f - reálne číslo na dve desatinné miesto

Funkcia s parametrami a bez návratovej hodnoty

Príklad č.35

Program, ktorý vypočíta obsah štvorca s využitím vlastnej funkcie. Vytvorená funkcia bude obsahovať jeden vstupný parameter  x (veľkosť strany štvorca), ktorú zadáme vo funkcií main. Obsah štvorca sa vypočíta vo funkcií obsah teda funkcia je bez návratovej hodnoty.

#include < stdio.h >	
#include < conio.h >

void obsah(float);		//deklarácia funkcie obsah

void main(void)
{
   float a;

   clrscr();
   printf("Zadaj stranu a: ");	
   scanf("%f",&a);
   obsah(a);				// volanie funkcie obsah
   getch();
   }

void obsah(float x)			//definícia funkcie 
{
   float s;

   s=x*x;
   printf("Obsah štvorca = %.2f",s);
   }
Funkcia s parametrami a s návratovou hodnotou

Príklad č.36

Program, ktorý sčíta dve celé čísla s využitím vlastnej funkcie s parametrami a s návratovou hodnotou. 

#include < stdio.h>

int sucet(int, int);		//deklarácia funkcie sucet
 
void main(void)
{
   int a, b, c;
  
   a = 5;            //priradenie hodnôt
   b = 2;
   c = sucet(a, b);            //volanie funkcie
   printf("sucet je %d", c);   //tlač výsledku
   }
 
int sucet(int x, int y)  	//definícia funkcie
{
   int k;
 
   k = x + y;             //operácia súčtu
   return (k);            //návrat výsledku operácie
   }

Funkcia nám prevedie jednoduchý súčet dvoch čísel.
  x, y – formálne parametre funkcie,  a, b – skutočné parametre
 Pri volaní funkcie sucet() sa hodnoty a, b prekopírujú do x, y a funkcia teda pracuje s kópiami týchto hodnôt.
Zmena x, y vo funkcii sucet() nemá vplyv na zmenu hodnôt a, b vo funkcii main.
Príkaz return vo funkcii spôsobí uloženie návratovej hodnoty do premennej c.

 

Rekurzivita funkcií

 

V jazyku C môžeme funkcie vyvolávať rekurzívne. Pri priamej rekurzivite funkcia vo svojom tele volá samu seba, pri nepriamej rekurzivite sa vzájomne vyvolávajú dve funkcie. Typickým príkladom rekurzívnej funkcie je výpočet faktoriálu pre celého kladné čísla.

 

Priklad č.37

Program, ktorý vypočíta faktoriál pre celé kladné číslo n s využitím rekurzívnej funkcie. 

#include < stdio.h>

unsigned long fakt(unsigned int);  // deklarácia funkcie faktoriálu

void main(void)
{
   unsigned int a;
 
   printf("Zadaj cele kladne číslo: ");
   scanf("%u", &a);  				       //načítanie čísla
   printf("Faktorial %u je %lu", a, fakt(a)); //tlač výsledku
   }

unsigned long fakt(unsigned int n)	//definícia funkcie pre výpočet faktorialu
{
   if(n==0)
     return (1);              //test, či n nie je rovne 0
   else
     return(n * fakt(n-1));   //ak nie, rekurzivne volanie fcie
   }

 Funkcia pre výpočet faktoriálu je napísaná podľa vzťahu n!=n*(n-1)!Je typu unsigned long, keďže výsledok bude kladný a podstatne väčší ako vstup.
 Parameter funkcie je bezznamienkový, keďže nemá zmysel definovať faktoriál pre záporné čísla.
Pre
n=0 je výpočet faktoriálu ukončený (lebo 0!=1), pre ostatné hodnoty funkcia volá samu seba s parametrom zníženým o 1.

 

 

 Vytvorte program pre výpočet povrchu a objemu kvádra.(SWITCH a vlastné funkcie)

 Vytvorte program, ktorý vypočíta obsah a obvod kruhu.(SWITCH a vlastné funkcie)

Vytvorte program, ktorý vytlačí max. číslo z 2 celých čísel pomocou ternálneho operátora a vami vytvorenej funkcie.(vlastná funkcia)
Vytvorte program, ktorý vypočíta x-tú mocninu z čísla.(vlastná funkcia)