1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//hlavickove subory //deklaracie funkcii, typov, ... int main() { //deklaracie premennych pre main //prikazy return 0; } //definicie (kod) dalsich funkcii |
1 2 3 4 5 6 7 8 9 10 11 |
//nezabudajte na popis funkcie v komentari TYP_NAVRATOVEJ_HODNOTY NAZOV_FUNKCIE( TYP1 PARAM1, TYP2 PARAM2, ... ) { //deklaracie lokalnych premennych pre funkciu TYP PREMENNA1, PREMENNA2, ... ; TYP PREMENNE_INEHO_TYPU; //prikazy return VYRAZ; } |
1 2 3 |
printf("Hello world\n"); //vypise zadany retazec: Hello world a koniec riadku printf("%d", VYRAZ); //vypise hodnotu vyrazu ako desiatkove cele cislo scanf("%d", &PREMENNA); //nacita desiatkove cislo zo vstupu a ulozi ho do premennej |
Viac info: https://en.wikipedia.org/wiki/Printf_format_string
Typ | Popis | Konštanta | Formátovací reťazec |
int |
celé číslo: 32 bitové alebo 16 bitové, so znamienkom | 189 | %d |
0x189 | %x |
||
unsigned |
kladné celé číslo bez znamienka | 189 | %u |
long long |
64-bitové číslo so znamienkom | 189LL | %lld |
float |
desatinné číslo s malou presnosťou | 1.89f | %f |
double |
desatinné číslo s väčšou presnosťou | 1.89 | %lf |
7.3e-4 | %.1le |
||
char |
8-bitové číslo, jeden znak | ‚a‘ | %c |
Implicitná:
int / double
konvertuje na double / double
, výsledok je double
int + char
konvertuje na int + int
, výsledok je int
int = double
konvertuje na int
, stratí sa desatinná časť/hrozí pretečeniechar = int
konvertuje na char
, stratia sa bity (zostane posledných 8 bitov, zvyšok po delení 256) void f(int): f(3.3)
-> stratí presnosť, volá sa f
s parametrom 3 Explicitná:
(int) (x/y)
-> delia sa double
čísla, výsledok je orezaný na int
(int) x/y
-> x sa oreže na int
, ale potom sa opäť skonvertuje na double
a delenie je s double
číslami (a teda aj výsledok)
Základná aritmetika:
1 2 3 4 5 6 |
c = a + b; c = a - b; c = a * b; c = a / b; c = a % b; //zvysok po deleni, iba pre cele cisla |
Priradenie spojené s operáciou:
1 2 3 |
//zjednodusenie pre: c = c + a c += a; //detto: -= *= /= %= |
Zvýšenie hodnoty o 1:
1 2 3 4 5 6 7 8 9 |
//post-inkrement c = a++; //to iste ako: c = a; a = a + 1; //pre-inkrement c = ++a; //to iste ako: a = a + 1; c = a; //podobne pre/post-dekrement: operator -- |
Riadi sa (zväčša) štandardnými matematickými zápismi:
1 |
a * -b // a * (-b) |
1 2 |
a + b * c // a + ( b * c ) a || b && c // a || ( b && c ) |
1 |
a * b / c *d // (((a * b) / c) * d ) |
1 |
a = b = c + d // (a = (b = (c+d))) |
Plná tabuľka a popis: http://en.cppreference.com/w/c/language/operator_precedence
Pri zápise je kvôli čitateľnosti vhodné zložité výrazy rozdeliť, a manuálne ozátvorkovať netriviálne časti.
1 2 3 4 5 6 7 8 9 10 11 12 |
//zakladne podmienky: a == b //zhoda, ma a tu istu hodnotu ako b ? a != b //nezhoda, ma a roznu hodnotu ako b ? a < b //je a mensie ako b ? a <= b //je a mensie alebo rovne ako b ? a > b //je a vacsie ako b ? a >= b //je a vacsie alebo rovne ako b ? //logicke operatory !P1 // nie P1 P1 && P2 // P1 a zaroven P2 P1 || P2 // P1 alebo P2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//vetvenie if ( PODMIENKA1 ) { //kod vnutri sa vykonava, iba ak podmienka1 plati, t.j. prislusny vyraz ma nenulovu hodnotu PRIKAZY } else if ( PODMIENKA2 ) { //kod vnutri sa vykonava, iba ak podmienka1 neplati (else) a podmienka2 plati (if) PRIKAZY } else { //kod vnutri sa vykonava, iba ak podmienka1 ani podmienka2 neplatia PRIKAZY } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//vetvenie podla konstanty switch( VYRAZ ) { case NAVESTIE1: //kod sa vykonava, ak VYRAZ ma hodnotu NAVESTIE1 PRIKAZY break; //ak sa break vynecha, pokracuje sa kodom v dalsom navesti case NAVESTIE2: //kod sa vykonava, ak VYRAZ ma hodnotu NAVESTIE2 PRIKAZY break; default: //kod sa vykonava, vo vsetkych ostatnych pripadoch break; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// ak PODMIENKA je pravdiva, vykona sa telo cyklu, a znova sa otestuje podmienka, // ak PODMIENKA praviva nie je, pokracuje sa v programe za prikazom while while ( PODMIENKA ) { PRIKAZY_V_TELE_CYKLU } // ak PODMIENKA je pravdiva, opatovne sa vykonava telo cyklu (minimalne raz), inak sa pokracuje v programe do { PRIKAZY_V_TELE_CYKLU } while ( PODMIENKA ); // najprv sa vykona INIT // potom sa otestuje PODMIENKA, ak je pravdiva, vykona sa telo cyklu, inak sa pokracuje v programe za cyklom // ked skonci telo cyklu, vykona sa INKREMENT, a pokracuje sa testovanim podmienky for ( INIT ; PODMIENKA ; INKREMENT ) { PRIKAZY_V_TELE_CYKLU } |
1 2 3 4 5 6 |
//typicke pouzitie na opakovanie kodu n-krat //v jazyku C musi byt i deklarovane ako premenna na zaciatku funkcie for ( i=0 ; i<n ; i++ ) { PRIKAZY_CO_SA_MAJU_n_KRAT_OPAKOVAT } |
1 2 3 |
//specialne riadiace konstrukcie break; // vyskoci z tela cyklu von continue; // presunie sa riadenie na podmienku cyklu (vo for prikaze najprv na INKREMENT) |
Polia predstavujú postupnosť za sebou v pamäti uložených údajov sprístupniteľných cez index.
1 2 3 4 5 6 7 8 9 |
//deklaracia pola, nedefinovany obsah, maximum KAPACITA prvkov TYP NAZOV[KAPACITA]; //deklaracia pola s vymenovanim prvkov, KAPACITA sa moze, ale nemusi vynechat int prvocisla[] = {2,3,5,7,11,13,17}; //spristupnenie prvku - operator indexovania - indexy od nuly po KAPACITA-1 a = pole[0]; //precita sa prvy prvok a zapise do premennej a pole[i] = a; //obsah premennej a sa zapise do pola na index ulozeny v premennej i |
Viac detailov k inicializácii: http://en.cppreference.com/w/c/language/array_initialization
Viacrozmerné polia
Štandardné polia, ktorých prvkami sú iné polia.
1 2 3 4 5 |
//pole troch poli, z ktorych kazde ma 5 prvkov typu int int pole2D[3][5]; //pole NS stranok po NR riadkoch po NC+1 znakoch kazdy riadok char kniha[NS][NR][NC+1]; |
Reťazce
Pole znakov, na ktorých konci je znak '\0'
.
1 2 3 4 5 6 7 8 |
//pripravene miesto na retazec s 5 znakmi char retazec[5+1]; //inicializacia pola (retazec, ktory sa da citat aj menit) char text[] = "lorem ipsum"; //pointer na konstantny retazec (da sa iba citat) const char *str = "lorem ipsum"; |
S reťazcami sa dá robiť v jazyku C veľa vecí cez knižničné funkcie, viď príslušné cvičenie a literatúru.
Adresa premennej sa získa cez operátor &
.
Smerník je premenná obsahujúca pamäťovú adresu:
*
, dá sa robiť smerníková aritmetika
1 2 3 4 5 6 7 |
int i; //premenna typu int void * ptr; //beztypovy smernik int* pi; //typovy smernik ptr = &i; //adresovy operator pi = (int*) ptr; //pretypovanie smernikov *pi = 2; //spristupnovaci operator, na adresu kam ukazuje pi (do i) sa zapise 2 |
Smerníková aritmetika:
1 2 3 4 5 6 7 8 9 |
int pole[100]; //pole int* pi; //typovy smernik pi = &pole[10]; //adresa 11. prvku pi = pole+10; //to iste co predosly riadok cez smernikovu aritmetiku *(pi+1) = pi[1]; //nic sa nestane, nalavo aj napravo je ten isty vyraz printf("%d\n", pi-pole); //malo by vypisat 10 - o kolko intov dalej ukazuje pi od pole |
Štruktúry logicky združujú viacero údajov do 1 celku. Syntax deklarácie:
1 2 3 4 |
struct TAG { //deklaracie poloziek - ako keby sme deklarovali premenne //polozky mozu byt lubovolneho typu: zakladne typy, existujuce struktury, polia, smerniky }; |
Často sa spája deklarácia s vytvorením nového typu:
1 2 3 4 5 6 7 |
typedef struct _datum { char den; char mesiac; short int rok; } Datum; |
Operácie so štruktúrou:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//deklaracia premennej struct _datum d1; //deklaracia s nastavenim hodnot Datum d2 = {22,4,1999}; //deklaracia smernika Datum *p1 = &d1; //kopirovanie hodnot d1 = d2; //spristupnovaci operator pre strukturu d1.rok = 2000; //spristupnovaci operator pre smernik p1->den = 15; |
Enumerácie združia pomenovanie konštánt do 1 typu. Namiesto:
1 2 3 4 |
#define JANUAR 1 #define FEBRUAR 2 #define MAREC 3 ... |
vytvoríme typ
1 2 3 |
enum _mesiac { JANUAR=1, FEBRUAR, MAREC, ..., DECEMBER }; |
Tento typ môžeme používať ďalej ľubovoľne v kóde. Hodnoty sa správajú ako int, ale ako konštanty môžem použiť pomenované názvy:
1 2 3 4 |
enum _mesiac m; for (m = JANUAR; m <= DECEMBER; M++) printf("%d ", m); //pozor: vypise cislo |
malloc
(neinicializované pole, t.j. nie je definovaný obsah), alebo calloc
(naplní pole nulami). Funkcia vráti adresu alokovanej pamäte, ktorú si uložíme do smerníkovej premennej. realloc
. free
. Po volaní free je vhodné smerník vynulovať, ak sa s ním nebude ďalej pracovať.Viacrozmerné dynamické polia
Typicky ich reprezentujeme poľom smerníkov (dynamickým, alebo aj statickým), pričom každý smerník odkazuje na dynamicky alokované pole.