<< home >>
Svojvoľný úvod do programovania v jazyku C
<<- ->>


  • Okomentované zdrojáky na úvod

OKOMENTOVANÉ ZDROJÁKY NA ÚVOD

  1. premenné a aritmetické operácie, symbolické konštanty, dátové typy a triedy, oblasti platnosti, operátory, cykly for, while, do, I/O funkcie, typová konverzia, logické a bitové operácie, ...

  2. inicializácia premenných, switch, break, continue, reťazec ako pole znakov, ...

  3. smerníky, volanie funkcie odkazom, smerníková aritmetika, ...

  4. pole smerníkov, ...

  5. argumenty, smerník na funkciu, smerník na smerník poľa znakov, ...

  6. štruktúra, pole štruktúr, smerník na štruktúru, štruktúry s odkazom na seba, ...

  7. bitové polia, unióny, ...


premenné a aritmetické operácie, symbolické konštanty, dátové typy a triedy, oblasti platnosti, operátory, cykly for, while, do, I/O funkcie, typová konverzia, logické a bitové operácie, ...

#include <stdio.h>

/* symbolicke konstanty bez bodkociarky a priradenia */
/* fsetky realne konstanty sa povazuju za typ double */
#define JEDNA_DESATINA 0.1
#define DESAT 10
#define JEDNA 1

/* ine konstanty v tomto pripade irelevantne */
#define REALNA_BEZNA 0.123456
#define REALNA_VEDECKA 123.456e-18
#define INA_REALNA_VEDECKA 0.05E8
#define LONGOVA 123L
/* alebo ak by celociselna konstana bez L prekrocila hodnotu intu tiez sa povazuje za long */
#define OSMICKOVA 077
#define LONGOVA_OSMICKOVA 077L
#define SESTNASTKOVA 0xff
#define INA_SESTNASTKOVA 0XFF
#define LONGOVA_SESTNASTKOVA 0xffL

#define ZNAK 'a'
#define RETAZEC "toto je retazec"
#define PRAZDNY_RETAZEC ""

/* extern a static sa inicializuju iba raz pred vykonanim programu */
/* implicitne su inicialiovane na nulu ale zvykne sa to uviest */

/* auto sa inicializuju pri kazdom volani funkcie kde sa nachadzaju */
/* implicitne maju nedefinovanu nahodnu hodnotu */

/* externa (globalna) premenna */
int glogloglo; /* definicia */


void main(void)
{

  extern int glogloglo; /* deklaracia (nevyhradzuje miesto v pamati */
  /* ak je globalna premenna deklarovana v inom subore treba pisat extern */
  /* v tomto pripade je slovo extern irelevantne */

  /* trieda static v lokalnej funkcii premennej zachovava jej hodnotu */
  /* aj po opusteni funkcie */
  /* v tomto pripade nemame funkcie a lokalne premenne */


  /* zakladne datove typy */
  int cele, i;       /* aj unsigned */
  float desatinne=1.0;
  char znak;
  short kratke_cele; /* aj unsigned short */
  long dlhe_cele;    /* aj unsigned long */
  double desatinne_dvojpresne;

  /*
     z nich mozno vytvarat
     pole
     struktury
     uniony
     smerniky
     funkcie
  */

  while (desatinne<2.0) { /* desatinnu konstantu treba pisat s desatinnou ciarkou a nulou */
    desatinne += JEDNA_DESATINA;
    printf("%5.2f\n", desatinne); /* cislo ma zaberat najmenej 5 miest a 2 desatine miesta */
  }

            cele = desatinne; /* automaticka konverzia */
            printf("%10i\n", cele);

            /*
               pred aritmetickymi operaciami s typmi char a int sa
               chary automaticky konvertuju na inty
            */

            cele = (int)desatinne; /* typova konverzia */
            printf("%10d\n", cele);

  for (i=0; i<DESAT; i++) {
    desatinne -= JEDNA_DESATINA;
    printf("%2.5f\n", desatinne);
  }

            printf("\n");
            desatinne=(float)JEDNA;

  do {
    desatinne += JEDNA_DESATINA;
    printf("%5.2f\n", desatinne); /* cislo ma zaberat najmenej 5 miest a 2 desatine miesta */
  } while (desatinne<2.0);


  putchar(getchar());
  putchar('\n');
  /*
     znak je v apostrofoch a retazec v uvodzovkach
     napr '\n' je jeden znak a "\n" je retazec obsahujuci jeden znak a zakonceny znakom '\0'
  */

  /*
     ak chcem fciou getchar testovat aj koniec suboru (EOF <0 alebo -1>)
     treba pocitat s typom int a nie char
  */

  /*
     biele znaky
     ' '  medzera
     '\t' tabelator
     '\n' koniec riadku
  */

  printf("\h\o\v\n\o\ \v \r\i\t\i");
  printf("\n \t \\ \' \" \% \n");

  /*
     aritmeticke operatory unarne
     -
     aritmeticke operatory binarne
     + - * / %
     relacne operatory (maju nizsiu prioritu nez aritmeticke)
     > >= < <=
     operatory rovnosti (maju este nizsiu prioritu)
     == !=
     logicke spojky (vyhodnotenie zlava doprava a ak je vysledok jasny dalej sa nevyhodnocuje)
     && || (maju este este nizsiu prioritu) (&& ma vyssiu prioritu nez ||)
     unarny operator negacie
     !
     operator priradenia (najnizsia priorita)
     =
  */
    
  /*
     i++ ++i j++ --j je v poriadku
     i++ + j++ je v poriadku
     (i+j)++ je nepripustna blbost
  */

  /*
     bitove operacie
     &  log sucin po bitoch
     |  log sucet po bitoch
     ^  nonekvivalencia po bitoch
     << bitovy posuv vlavo
     >> bitovy posuv vpravo
     ~  unarny operator jednotkoveho doplnku
  */

  /*
     ternarny podmieneny vyraz
     v1 ? v2 : v3
  */
}

inicializácia premenných, switch, break, continue, reťazec ako pole znakov, ...

#include <stdio.h>
/* lokalne premenne mozno deklarovat aj vnutri akehokolvek bloku */

/*
   polia (aj retazce su odovzdavane funkciam odkazom na prvy (nulty) prvok
   funkcia moze pole menit
*/

/* platnosti
   externa premenna ma platnost do konca suboru
                    ak v druhom subore je deklaracia extern premenna z ineho suboru
                    tak tato plati aj pre cely druhy subor
                    (vo vsetkych suboroch moze byt iba v jednom definovana externa premenna
                     v ostatnych suboroch musi byt deklarovana slovom extern alebo cely
                     subor includnuty #include "subor")
   trieda static (interne-lokalne aj externe-globalne) na rozdiel od auto existuju stale
   static premenne (aj funkcie) su sukromne pre dany subor, z ineho suboru ich nevidno
   registrove premenne (iba tri iba typu int, char alebo pointer) nie je mozne
                       ziskat adresu register premennej
*/

/* inicializacia
   extern a static na nulu
   polia extern a static mozno inicializovat int pole[4]={0,0,0,0};
                         char retazec="debil"
                         char retazec={'d','e','b','i','l','\0'}
   auto polia nemozno takto inicializovat
*/


int main(void)
{
  char znak;

  puts("Zadaj znak ");
  znak=getchar();

  switch (znak) {
    case '0' : puts("Je to nula"); break;
    case 'a' : puts("Je to male a"); break;
    case 'A' : puts("Je to velke A"); break;
    default       : puts("I tak dobre"); break;
  }

  /* break okamzite vyskoci z najvnutornejsieho cyklu */
  /* continue sposobi navrat na zaciatok najvnutornejsieho cyklu v dalsej iteracii */

  return(0);

}

smerníky, volanie funkcie odkazom, smerníková aritmetika, ...

#include <stdio.h>

void vymena(int *p_x, int *p_y)
{
  int pompo;

  pompo=*p_x;
  *p_x=*p_y;
  *p_y=pompo;
}

int main(void)
{
  int a=15;
  int b=255;

  printf("%5X %5X\n", a, b);
  vymena(&a, &b);
  printf("%5x %5x\n", a, b);

  return(0);
}

/* meno pola je vlastne smernik na nulty prvok
   p_pole=&pole[0] je to iste ako p_pole=pole
   prvok pola pole[i] je to iste ako *(pole+i)
   p_pole[i] je to iste ako *(p_pole+i)
   pole+i je adresa i-teho prvku pola

   smernik je premenna
   meno pola je konstanta

   smerniky mozno porovnanat (<, <=, >, >=, ==, !=) ak ukazuju na prvky jedneho pola
   medzi sebou
   alebo s NULL

   k smernikom mozno pripocitavat a odpocitavat cele cislo

   dva smerniky mozno odcitat (ziskam dlzku casti pola) ak ukazuju na prvky jedneho pola
*/

pole smerníkov, ...

#include <stdio.h>

int main(void)
{
  char *textik;
  int pocet=0;

  textik="Toto je pole 22 znakov";
  puts(textik);

  while (*textik++)
    pocet++;

  printf("Pocet znakov v retazci je %i\n", pocet);

  return(0);
}

/* pole retazcov (pole poli) mozno definovat ako pole smernikov char *pole[pocet] */

/*
   taketo pole poli (pole smernikov) mozno inicializovat napr
   static char *pole[]={"janko","marienka","jezibaba","pani ucitelka"};

   potom pole[1] bude smernik na retazec marienka atd
*/

/*
   tiez je napr rovnaky zapis int a[10][10] a zapis int *a[10]
   pole smernikov potrebuje o nieco viac pamatoveho miesta
   vyzaduje explicitnu inicializaciu
*/

argumenty, smerník na funkciu, smerník na smerník poľa znakov, ...

/* program spustit s kopcom argumentov */
#include <stdio.h>

void main(int argc, char **argv)
/* void main(int argc, char *argv[]) */
{
  int i;

  while (--argc)
  /* for (i=1; i<argc; i++) */
    printf("%s ", *++argv);
    /* printf(%s ",argv[i]); */

  printf("\n");

}

/*
   pointer mozno definovat aj na funkciu
   int (*fcia)() ... fcia je pointer na funkciu vracajucu int

   bez prvych zatvoriek by bolo
   int *fcia()   ... fcia je funkcia vracajuca pointer na int
*/

štruktúra, pole štruktúr, smerník na štruktúru, štruktúry s odkazom na seba, ...

/*
   nad strukturou mozno vykonavat iba dve operacie
   ziskanie jej adresy operatorom &
   pristup k jednotlivym clenom . (alebo cez smernik ->)
*/

#include <stdio.h>

typedef struct osoba {
  char *meno;
  double plat;
  int vek;
} POLITIK;

POLITIK glo={"GLogac", 400000.00, 87};

int main(void)
{
  struct osoba vladimir, mikulas, *p_mikulas;
  POLITIK gustav;

  /* mozno vytvorit aj pole struktur */
  POLITIK debil[120];
  /*
     a pristupovat napr k prvemu politikovi v parlamente cez prvok debil[0] (je strukturou)
  */

  p_mikulas=&mikulas;

  p_mikulas->meno="Miki";
  p_mikulas->plat=840000.00;
  p_mikulas->vek=43;

  debil[0]=*p_mikulas;
  /* debil[0]=mikulas; */

  (*p_mikulas).vek=(int)p_mikulas->vek*1.2;
  glo.plat=(int)mikulas.plat/2;


  printf("%10s %8.2f Sk   %i\n", glo.meno, glo.plat, glo.vek);
  printf("%10s %8.2f Sk   %i\n", p_mikulas->meno, p_mikulas->plat, p_mikulas->vek);

  return(1);
}

/*
   struktury mozu byt aj vnorene alebo odkazovat sami na seba (cez smerniky) napr

   typedef struct osoba {
     char *meno;
     double plat;
     int vek;
     struct osoba *ritolizac;
   } POLITIK;

*/

bitové polia, unióny, ...

/*
   bitove polia su neznamienkove
   ukladaju sa iba v premennych int (unsigned)
   nie su polami a nemaju adresy (nemozno aplikovat &)

   byva problem s prenositelnostou medzi strojmi bo niektore
   ukladaju bitove polia sprava a ine zlava

   mozu byt realizovane dvomi sposobmi
        definovanim mnoziny masiek
                    #define X 01
                    #define W 02
                    #define R 04
                    a aplikovat operatory posuvu, maskovania a jednotkoveho doplnku
        definovanim bitovych poli v strukture
                    struct {
                      unsigned is_x : 1;
                      unsigned is_w : 1;
                      unsigned is_r : 1;
                    } atributik
                    (premenna atributik obsahuje tri jednobitove polia s klasickym
                     strukturovym pristupom atributik.is_x atd)
*/

/*
   uniony definujeme rovnako ako struktury ale v jednom casw moze obsahovat iba jeden clen
   union manipuluje s roznymi druhmi dat v jednej oblasti pamati
   pristup k clenom unionu podobne ako u struktur (. ->)
*/

void main(void) {}

<<- ->>