Download - Procedur álne programovanie: 4 . prednáška
![Page 1: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/1.jpg)
Procedurálne programovanie:4. prednáška
Gabriela Kosková
![Page 2: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/2.jpg)
Obsah
1. opakovanie (4 príklady)
2. preprocesor
3. príklady (4)
4. funkcie a práca s pamäťou
5. príklady (4)
![Page 3: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/3.jpg)
Procedurálne programovanie:Práca so súborom - opakovanie v príkladoch
![Page 4: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/4.jpg)
Príklad 1
program sčíta celé čísla v súbore ceny.txt. Čísla v súbore predchádza vždy niekoľko
znakov '$' (bez medzery).
Príklad je na vrátenie znaku na vstup.
![Page 5: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/5.jpg)
#include<stdio.h>
int main() { FILE *fr; int c; float cena, suma = 0.0;
fr = fopen("ceny.txt", "r");
while(!feof(fr)) { while((c = getc(fr)) == '$') ; ungetc(c, fr); fscanf(fr, "%f", &cena); printf("%f\n", cena); suma += cena; while(!feof(fr) && (c = getc(fr)) != '$') ; ungetc(c, fr); } printf("suma: %.2f\n", suma);
fclose(fr); return 0;}
if((fr = fopen("ceny.txt", "r")) == NULL) { printf("Nepodarilo sa otvorit subor.\n"); return;}
if(fclose(fr) == EOF) printf("Nepodarilo sa zatvorit suobor.\n");
![Page 6: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/6.jpg)
Príklad 2
program načíta rozmer n a nakreslí do súboru sach.txt sachovnicu n x n, kde čierne
políčka bude reprezentovať znak # a biele políčka medzera
![Page 7: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/7.jpg)
#include<stdio.h>
int main() { int i, j, n; FILE *fw;
if ((fw = fopen("sach.txt", "w")) == NULL) { printf("Subor sa nepodarilo vytvorit.\n"); return 0; }
printf("Zadajte rozmer sachovnice: "); scanf("%d", &n);
for (i=1; i<=n; i++) { for (j=1; j<=n; j++) if ((i%2 && !(j%2)) || (!(i%2) && j%2)) putc('#', fw); else putc(' ', fw); putc('\n', fw); }
if (fclose(fw) == EOF) printf("Subor sa nepodarilo zatvorit.\n"); return 0;}
![Page 8: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/8.jpg)
Príklad 3
Kontrola otvorenia dvoch súborov
... FILE *fr, *fw;
if ((fr = fopen("data.txt", "r")) == NULL) { printf("Subor data.txt sa nepodarilo vytvorit.\n"); return 0; } if ((fw = fopen("vystup.txt", "w")) == NULL) { printf("Subor vystup.txt sa nepodarilo vytvorit.\n"); if(fclose(fr) == EOF) printf("Subor data.txt sa nepodarilo zatvorit.\n"); return 0; }... Pred ukončením programu treba
zatvoriť všetky otvorené súbory
![Page 9: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/9.jpg)
Príklad 4
Kontrola zatvorenia dvoch súborov
... FILE *fr, *fw;...
if(fclose(fr) == EOF || fclose(fw) == EOF) printf("Niektory subor sa nepodarilo zatvorit.\n");
...
Skrátené vyhodnocovanie podmienok: ak sa podarí zatvoriť prvý súbor, už je zrejmé, že OR má hodnotu 1 a už sa druhá časť podmienky
nevyhodnocuje, teda druhý súbor sa nezatvorí
![Page 10: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/10.jpg)
Procedurálne programovanie:Preprocesor
![Page 11: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/11.jpg)
Činnosť preprocesora
• spracováva zdrojový text PRED kompilátorom• zamieňa text, napr. identifikátory konštánt za
číselné hodnoty• vypustí zo zdrojového textu všetky komentáre• prevádza podmienený preklad• nekontroluje syntakticú správnosť programu
• riadok, ktorý má spracovávať preprocesor sa začína znakom #
![Page 12: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/12.jpg)
Konštrukcie pre preprocesor
• definovanie makra
#define meno_makra text
• zrušenie definície makra
#undef meno_makra
• podmienený preklad v závislosti na konštante konst
#if konst
#elif #else #endif
![Page 13: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/13.jpg)
Konštrukcie pre preprocesor
• vloženie textu zo špecifikovaného súbora zo systémového adresára
#include <filename>
• vloženie textu zo špecifikovaného súbora v adresári používateľa
#include "filename"
• výpis chybových správ vo fáze predspracovania
#error text
![Page 14: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/14.jpg)
Konštrukcie pre preprocesor
• podmienený preklad v závislosti od toho, či je makro definované, alebo nedefinované
#ifdef meno_makra
#elif #else #endif
• podmienený preklad v závislosti od toho, či je makro nedefinované, alebo definované
#ifndef meno_makra
#elif #else #endif
![Page 15: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/15.jpg)
Konštanty - makrá bez parametrov
• symbolické konštanty• používajú sa často (zbavujú program "magických čísel")• väčšinou definované na začiatku modulu• platnosť konštánt je do konca modulu• náhrada konštanty hodnotou - rovoj (expanzia) makra
![Page 16: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/16.jpg)
Pravidlá pre písanie konštánt
• mená konštánt - veľkými písmenami• meno konštanty je od hodnoty oddelené apsoň jednou
medzerou• za hodnotou by mal byť vysvetľujúci komentár• nové konštanty môžu využívať skôr definované konštanty• ak je hodnota konštanty dlhšia ako riadok, musí byť na
konci riadku znak \ (nie je súčasťou makra)
![Page 17: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/17.jpg)
Príklady defninovania konštánt
#define MAX 1000#define PI 3.14#define DVE_PI (2 * PI)#define MOD %#define AND &&#define MENO_SUBORU "list.txt"#define DLHA_KONSTANTA Toto je dlha konstanta, \ ktora sa nezmesti do jednoho riadku.
• za hodnotou nie je ;• medzi menom konštanty a jej hodnotou nie je =
![Page 18: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/18.jpg)
Príklad požitia konštanty: výpočet obsahu kruhu
#include <stdio.h>#define PI 3.14
int main(){ double r;
printf("Zadajte polomer: "); scanf("%lf" &r); printf("Obvod kruhu s polomerom %f je %f\n", r, 2 * r * PI); return 0;}
![Page 19: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/19.jpg)
Príklad použitia konštanty: malé písmená zmení na veľké#include <stdio.h>#define POSUN ('a' - 'A')#define EOLN '\n'#define PRED_MALE '*'
int main() { int c;
while((c = getchar()) ! = EOLN) { if (c >= 'a' && c <= 'z') { putchar(PRED_MALE); putchar(c - POSUN); } else putchar(c); } return 0;}
ak je symbolickou konštantou výraz, vhodné je uzavrieť ho do zátvoriek
malé písmeno zmení na veľké a pred neho vypíše '*', inak vypíše načítaný
znak
![Page 20: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/20.jpg)
Kedy sa nerozvinie makro
#define MENO "Katka"
...printf("Volam sa MENO");
printf("Volam sa %s", MENO);
• makro sa nerozvinie, ak je uzatvorené v úvodzovkách
vypíše sa: Volam sa MENO
vypíše sa: Volam sa Katka
![Page 21: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/21.jpg)
Prekrývanie definícií
• nová definícia prekrýva starú, pokiaľ je rovnaká (to ani nemá zmysel)
• ak nie je rovnaká:– zrušiť starú definíciu: #undef meno_makra– definovať meno_makra
#define POCET 10#undef POCET#define POCET 20
![Page 22: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/22.jpg)
Makro ako skrytá časť programu
• pri použití nie je makro ukončené bodkočiarkou:
#define ERROR { printf("Chyba v datach.\n"); }
if (x == 0) ERRORelse y = y / x;
![Page 23: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/23.jpg)
Makrá s parametrami
• krátka a často používaná funkcia vykonávajúca jednoduchý výpočet– problém s efektivitou (prenášanie parametrov a úschova návratovej
hodnoty je časovo náročnejšia ako výpočet)
– preto namiesto funkcie - makro (to sa pri preprocessingu rozvinie)
• je potrebné sa rozhodnúť medzi– funkcia: kratší ale pomalší program
– makro: rýchlejší ale dlhší program
![Page 24: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/24.jpg)
Makrá s parametrami
• nazývajú sa vkladané funkcie - rozvitie makra znamená, že sa meno makra nahradí jeho telom
• zátvorka, v ktorej sú argumenty funkcie - hneď za názvom makra (bez medzery)
#define je_velke(c) ((c) >= 'A' && (c) <= 'Z')
definícia makra
ch = je_velke(ch) ? ch + ('a' - 'A') : ch;
v zdrojovom súbore
ch = ((ch) >= 'A' && (ch) <= 'Z') ? ch + ('a'-'A') : ch;
rozvinie sa
![Page 25: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/25.jpg)
Makrá s parametrami
• telo makra - uzavrieť do zátvoriek, inak môžu nastať chyby, napr.:
#define sqrt(x) x * x...sqrt(f + g);
#define sqrt(x) ((x) * (x))...sqrt(f + g);
• správne
f + g * f + g; po rozvinutí makra
((f + g) * (f + g)); po rozvinutí makra
![Page 26: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/26.jpg)
Preddefinované makrá
• getchar() a putchar() (v stdio.h)
#define getchar() getc(stdin)
#define putchar(c) putc(c, stdout)
• makrá v ctype.h - makrá na určenie typu znaku– isalnum - vráti 1, ak je znak číslica alebo malé písmeno– isalpha - vráti 1, ak je znak malé alebo veľké písmeno– isascii - vráti 1, ak je znak ASCII znak (0 až 127)– iscntrl - vráti 1, ak je znak Ctrl znak (1 až 26)
– ...
– viac v Herout: Učebnice jazyka C
![Page 27: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/27.jpg)
Preddefinované makrá
• makrá v ctype.h - makrá na konverziu znaku– tolower - konverzia na malé písmeno– toupper - konverzia na veľké písmeno– toascii - prevod na ASCII - len najnižších 7 bitov je
významných
![Page 28: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/28.jpg)
Vkladanie súborov
• vkladanie systémových súborov < >• vkladanie súborov v aktuálnom adresári " "
#include <stdio.h>#include <ctype.h>#include "KONSTANTY.H"
![Page 29: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/29.jpg)
Podmienený preklad
• u väčších programov– ladiace časti - napr. pomocné výpisy
• program – trvalá časť
– voliteľná časť (napr. pri ladení, alebo ak je argumentom programu nejaký prepínač)
![Page 30: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/30.jpg)
Riadenie prekladu hodnotou konštantného výrazu
#if konstantny_vyraz cast_1#else cast_2#endif
ak je hodnota konštantného výrazu nenulová, vykoná sa časť 1, inak časť 2
#if 0 cast programu, co ma byt vynechana#endif
ak pri testovaní nechcete prekladať časť programu, namiesto /* */ (problém by robili vhniezdené komentáre)
![Page 31: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/31.jpg)
Riadenie prekladu hodnotou konštantného makra
• ak je program závislý na konkrétnom počítači
• ak na PC/AT - definujeme PCAT na 1, inak na 0
#define PCAT 1
#if PCAT #include <conio.h>#else #include <stdio.h>#endif
![Page 32: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/32.jpg)
Riadenie prekladu definíciou makra
• ak je program závislý na konkrétnom počítači
• ak na PC/AT - definujeme PCAT (bez hodnoty),
• stačí, že je konštanta definovaná
#define PCAT
#ifdef PCAT #include <conio.h>#else #include <stdio.h>#endif
• ak nie je definovaná konštanta#ifndef PCAT
• zrušenie definície makra#undef PCAT
![Page 33: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/33.jpg)
Operátory defined, #elif a #error
• #ifdef, alebo #ifndef zisťujú existenciu len jednoho symbolu, čo neumožňuje kombinovať viaceré
• ak treba kombinovať viaceré podmienky:
#if defined TEST #if !defined TEST
• #elif - má význam else-if
• #error - umožňuje výpis chybových správ (v priebehu preprocesingu - nespustí sa kompilácia)
![Page 34: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/34.jpg)
Operátory defined, #elif a #error - príklad
#if defined(ZAKLADNY) && defined(DEBUG) #define VERZIA_LADENIA 1#elif defined(STREDNY) && defined(DEBUG) #define VERZIA_LADENIA 2#elif !define(DEBUG) #error Ladiacu verziu nie je mozne pripravit!#else #define VERZIA_LADENIA 3#endif
![Page 35: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/35.jpg)
najprv musíme prebrať funkcie...
Oddelený preklad
• program sa delí na menšie časti - moduly– logicky sa program delí na časti
– je veľký
– pracuje na ňom viac programátorov
– aby bol prehľadný
• moduly– oddelené - zvlášť súbory
– obsahujú premenné a funkcie, ktoré môžu povoliť alebo zakázať používať inými modulmi
![Page 36: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/36.jpg)
Procedurálne programovanie:Príklady
![Page 37: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/37.jpg)
Príklad 1
program vypíše súčet prvých N čísel, kde N je symbolická konštanta
#include <stdio.h>#define N 5
int main() { int i, suma = 0;
for (i = 1; i <= N; i++) sum += i;
printf("Sucet prvych %d cisel je %d\n", N, suma); return 0;}
![Page 38: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/38.jpg)
Príklad 2
program použije makro na_tretiu(x), ktorá bude počítať tretiu mocninu a použije ho v rôznych výrazoch
#include <stdio.h>
#define na_tretiu(x) (x * x * x)
int main(void) { int i = 2, j = 3;
printf("%d^3 = %d", 3, na_tretiu(3)); printf("%d^3 = %d", i, na_tretiu(i)); printf("%d^3 = %d", 2+3, na_tretiu(2+3)); printf("%d^3 = %d", i*j+1, na_tretiu(i*j+1)); return 0;}
((x) * (x) * (x))
3^3 = 9
2^3 = 8
5^3 = 17
2+3*2+3*2+3 = 17 (nie 125)
7^3 = 19
2*3+1*2*3+1*2*3+1 = 19, (nie 343)
![Page 39: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/39.jpg)
Príklad 3
program zistí, či bola načítaná nula - pomocou makra citaj_int(x)
#include <stdio.h>
#define citaj_int(i) (scanf("%d", &i), i)
int main() { int j, k;
printf("Zadajte cele cislo: "); if((j = citaj_int(k)) == 0) printf("Bola nacitana nula.\n"); printf("Bolo nacitane cislo %d", k); return 0;}
![Page 40: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/40.jpg)
Príklad 4#include <stdio.h>
int main() { int x, y, nasobok = 0;
printf("Zadajte dve cisla: "); scanf("%d %d", &x, &y);
printf("%d * %d = ", x, y); for(; y>0; y--) { nasobok += x;
} printf("%d\n", nasobok); return 0;}
program vynásobí dve čísla len pomocou sčitovania, v cykle použijeme ladiace výpisy
#define LADENIE
#ifdef LADENIEprintf("\n(y: %d, nasobok: %d)\n", y, nasobok);
#endif
![Page 41: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/41.jpg)
Procedurálne programovanie: Funkcie a práca s pamäťou
![Page 42: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/42.jpg)
Funkcie a práca s pamäťou
• lokálne a globálne premenné
• pamäť
• funkcie
![Page 43: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/43.jpg)
Globálne a lokálne premenné
• stanovenie kde bude premenná dostupná– globálne premenné
• platnosť: od miesta definície po koniec súboru (nie programu - program sa môže skladať z viac súborov)
– lokálne premenné• definované vo funkciách
• platnosť: od definície po koniec funkcie
![Page 44: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/44.jpg)
Príklad: globálne definície
#include <stdio.h>
int i;
void prva(){...}
int j;
int druha(){...}
void main(){...}
premenná i je platná pre všetky 3 funkcie
premenná j je platná len pre funkcie:druha() a main()
![Page 45: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/45.jpg)
Lokálne premenné
#include <stdio.h>
int i1, i2;
void prva() { int i1, j1;...}
int j1, j2;
int druha(){ int i1, j1, k1;...}
globálna premenná i1 je prekrytá lokálnou premennou i1 (používať sa môžu premenné:i1, j1 (lokálne) a i2 (globálna))
dve globálne premenné: i2, j2 a tri lokálne premenné: i1, j1, k1.
![Page 46: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/46.jpg)
Inicializácia lokálnych a globálnych premenných
• lokálne premenné:– nie sú automaticky inicializované
• globálne premenné:– automaticky inicializované na 0 (0.0, \0)
(lepšie - nespoliehať sa na to)– vyhnúť sa globálnym premenným - môžu vniesť
zmätok do väčších programov!
![Page 47: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/47.jpg)
Alokácia pamäte
• každá premenná musí mať v čase svojej existencie pridelený pamäťový priestor
• akcia na vyhradenie pamäťového priestoru sa nazýva alokácia, ktorá môže byť– statická– dynamická
![Page 48: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/48.jpg)
Statická alokácia pamäte
• keď vieme prekladaču vopred povedať, aké máme na premenné pamäťové nároky– napr. vieme, že budeme potrebovať dve prenenné typu double a jednu
premennú typu char
• prekladač sám určí požiadavky pre všetky definované premenné a pri spustení programu sa pre ne alokuje miesto
• behom programu sa nemanipuluje s touto pamäťou• premenné majú alokované miesto od začiatku programu do jeho
konca• ruší ich operačný systém
![Page 49: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/49.jpg)
Statická alokácia pamäte
• vymedzuje miesto v dátovej oblasti• globálne premenné - statické• nie vždy to stačí
– napr. rekurzia alebo do pamäte potrebujeme načítať obsah súboru
– použiť dynamickú alokáciu, alebo vymedzenie pamäte v zásobníku
![Page 50: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/50.jpg)
Dynamická alokácia
• vymedzenie pamäte v hromade (heap)• za behu programu dynamicky prideliť (alokovať) oblasť
pamäte určitej veľkosti• pristupuje sa do nej prostredníctvom ukazovateľov
![Page 51: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/51.jpg)
Vymedzenie pamäte v zásobníku
• zaisťuje kompilátor pri volaní funkcie• väčšina lokálnych premenných definovaných vo funkciách• existencia týchto premenných začína pri vstupe do
funkcie a končí pri výstupe z funkcie• ak chceme prenášať hodnotu premennej medzi
jednotlivými volaniami funkcie - nemôže byť premenná alokovaná v zásobníku
![Page 52: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/52.jpg)
Funkcie
• jazyk C je založený na funkciách– kratšie programy majú jednu funkciu main()– väčšina má viac funkcií
• spracovanie programu – začína volaním funkcie main() – končí opustením funkcie main()
• funkcie nemôžu byť vhniezdené• nie procedúry - všetky funkcie vracajú hodnotu
– dajú sa použiť aj ako procedúry (vrátia void)
![Page 53: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/53.jpg)
Definícia funkcie
• definícia: určuje hlavičku aj telo funkcie• deklarácia: len špecifikuje hlavičku funkcie (meno, fyp
návratovej hodhoty, parametre)
– hlavička funkcie:
– definícia:
– volanie funkcie:
int max(int a, int b)
int max(int a, int b) { return (a > b ? a : b);}
x = max(10 * i, j - 15);
return h; - funkcia vráti hodnotu h
![Page 54: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/54.jpg)
Funkcia bez parametrov
– definícia funkcie:
– volanie funkcie:
int scitaj() { int a, b; scanf("%d %d", &a, &b); return (a + b);}
j = scitaj();
![Page 55: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/55.jpg)
Procedúry a dátový typ void
• formálne procedúry neexistujú, dá sa to obísť:
1. funkcia návratovú hodnotu vracia, ale nepotrebujeme ju, napr. čakanie na stlačenie klávesy (bez toho, aby nás zaujímalo, aká klávesa bola stlačená)
getchar();
(void) getchar();
čakanie na stlačenie klávesy
čitateľnejšie, niektoré prekladače to vyžadujú
![Page 56: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/56.jpg)
Procedúry a dátový typ void
2. funkcia sa definuje ako funkcia vracajúca typ void (nič), napr.
- volanie procedúry (funkcie):
vypis_int(a + b);
void vypis_int(int i){ printf("%d", i);}
![Page 57: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/57.jpg)
Príklad 1: použitie funkcie v programe#include <stdio.h>
int max(int a, int b) { return (a > b ? a : b);}
int main() { int x, y;
printf("Zadajte 2 cisla: "); scanf("%d %d", &x, &y); printf("Maximum: %d\n", max(x, y));
return 0;}
maximum z dvoch čísel
![Page 58: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/58.jpg)
Príklad 2: použitie funkcie v programe#include <stdio.h>#define N 5
int max(int a, int b) { return (a > b ? a : b);}
int main() { int i, x, y;
for (i=1; i<=N; i++) { printf("[%d] zadajte 2 cisla: ", i); scanf("%d %d", &x, &y); printf("Maximum: %d\n", max(x, y)); } return 0;}
maximum z dvoch čísel -
volanie funkcie viackrát
![Page 59: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/59.jpg)
Rekurzia :-)
• vysvetlenie slova rekurzia vo výkladovom slovníku:
- rekurzia: viď rekurzia
• funkcia, ktorá volá samu seba (väčšinou s inými parametrami)
![Page 60: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/60.jpg)
Rekurzívne funkcie
• funkcie v C môžu byť aj rekurzívne, napr. faktoriál:
#include <stdio.h>
int fakt(int n){ return ((n <= 0) ? 1 : n * fakt(n - 1));}int main() { int i;
printf("Zadajte cele cislo: "); scanf("%d", &i); printf("Fakrotial je %d\n", fakt(i); return 0;}
int fakt(int n){ return ((n <= 0) ? 1 : n * fakt(n - 1));}
![Page 61: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/61.jpg)
Rekurzívne funkcie
• pre n: 3
int fakt(int n){ return ((n <= 0) ? 1 : n * fakt(n - 1));}
• fakt(3): (3 <= 0) neplatí return(n * fakt(n-1)) 3 * fakt(2))
• fakt(2): (2 <= 0) neplatí return(n * fakt(n-1)) 2 * fakt(1))
• fakt(1): (1 <= 0) neplatí return(n * fakt(n-1)) 1 * fakt(0))
• fakt(0): (0 <= 0) platí return(1)
1
1
1
1
2
2
6
![Page 62: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/62.jpg)
Fibonacciho čísla
0, 1, 1, 2, 3, 5, 8, 13, 25, ...
f(1) = 0f(2) = 1f(n) = f(n-1) + f(n-2)
(čísla v postupnosti sú súčtom dvoch predošlých čísel)
• Pôvodný Fibonnaciho problém (1202) - ako sa môžu králiky rozmnožovať v ideálnych podmienkach
![Page 63: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/63.jpg)
Fibonacciho králiky
• Predpoklady:– máme novorodených párik králikov (samca a samičku)– králiky sa pária, keď majú jeden mesiac - na konci ich druhého
mesiaca sa samičke narodí pár králikov– králiky nezomierajú a samička vždy vyprodukuje nový pár
(jedného samčeka a jednu samičku) každý mesiac od svojho druhého mesiaca veku ďalej
• Hádanka, ktrorú Fibonacci položil:– koľko párov bude za jeden rok?
![Page 64: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/64.jpg)
Fibonacciho králiky
na konci prvého mesiaca sa pária, stále ešte len jeden pár
1
2
3
4
5
na konci druhého mesiaca sa samičke s bielym chvostíkom
narodí nový pár
na konci tretieho mesiaca sa samičke s bielym chvostíkom
narodí nový pár
na konci štvrtého mesiaca sa samičke s bielym chvostíkom a aj
samičke s hnedým chvostíkom narodí nový pár
![Page 65: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/65.jpg)
Fibonacciho čísla
štvorce špirály
semienka
kvetov
lastúra
![Page 66: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/66.jpg)
Fibonacciho čísla: rekurzívne
long fib(long n){ if (n <= 2) return n-1; else return fib(n-2) + fib(n-1);}
neefektívne, pretože sa veľakrát vypočítavajú tie isté čísla - iteratívne s použitím poľa - efektívne
6
4 5
32 3 4
21 1 2 32
21
![Page 67: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/67.jpg)
Rekurzia
• silná (krátky kód)
• neefektívna
• pokiaľ sa jej dá vyhnúť, nepoužívať (opakujúce sa výpočty radšej ukladať do pamäte)
![Page 68: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/68.jpg)
Fibonacciho čísla: iteratívne
long fib(long n){ if (n <= 2) return n-1; else { int n_1, n_2, i, sucet; n_1 = 0; n_2 = 1;
for(i=3; i<=n; i++) { sucet = n_1 + n_2; n_1 = n_2; n_2 = sucet; } return sucet; }}
iteratívne: nerekruzívne, s použitím cyklov
![Page 69: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/69.jpg)
Funkcie vracajúce int a iné typy
• funkcie vracajúce int – int môžeme vynechať
• funkcie vracajúce iný typ ako int– typ je potrebné uviesť
int max(int a, int b)
double max(double a, double b)
![Page 70: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/70.jpg)
Problémy s umiestnením definícií funkcií
• funkcia nemôže byť definovaná vo vnútri inej funkcie
• problém:– ak nejaká funkcia A()
volá inú fuknkciu B(),
ktorá je definovaná za
A(), (A() nemá
žiadne informácie o B())
int A(int x) { ... y = B((float) x); ...}
float B(float f) { ...}
![Page 71: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/71.jpg)
Problémy s umiestnením definícií funkcií
• menší problém, ak volaná funkcia (B()) vracia typ int
• ak nevracia typ int, je potrebné prekladaču určiť aspoň návratový typ a meno volanej funkcie pred jej volaním dvoma spôsobmi:
1. deklaráciou návratového typu a mena
2. pomocou funkčného prototypu
![Page 72: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/72.jpg)
Deklarácia návratového typu a mena
• umiestnená kdekoľvek (pred volaním)– vo vnútri volajúcej funkce (A())
– na globálnej úrovni
• starší spôsob: nie veľmi vhodné
![Page 73: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/73.jpg)
Deklarácia návratového typu a mena#include <stdio.h>
int A(int x) { int y; float B();
y = B(x); return y;}
float B(float f) { return (f * 3.14);}
...
vo vnútri funkcie
![Page 74: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/74.jpg)
Deklarácia návratového typu a mena#include <stdio.h>
float B();
int A(int x) { int y;
y = B(x); return y;}
float B(float f) { return (f * 3.14);}
...
na globálnej úrovni
![Page 75: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/75.jpg)
Použitie funkčného protorypu
• ANSI verzia jazyka C• umožňuje prekladaču naviac aj kontrolu počtu a typov
parametrov volanej funkcie (B())
• odporúča sa používať tento spôsob
![Page 76: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/76.jpg)
Použitie funkčného prototypu
#include <stdio.h>
float B(float r);
int A(int x) { int y;
y = B(x); return y;}
float B(float r) { return (r * 2* 3.14);}
...
funkčný prototyp na globálnej úrovni
funkčný prototyp sa dá použiť aj na lokálnej úrovni
![Page 77: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/77.jpg)
Konverzia návratovej hodnoty funkcie
• ak nie je návratový typ funkcie zhodný s návratovým typom výrazu - implicitná konverzia– napr.
– volanie:
int konverzia(double d){ return (d);}
int k;k = konverzia(4.5);
hodnota 4.5 bude pretypovaná na int - oreže sa a k bude mať hodnotu 4
![Page 78: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/78.jpg)
Parametre funkcií - volanie hodnotou
• predávanie parametrov hodnotou – parametre sú vo funkcii len čítané– každá zmena parametra je dočasná, je len v rámci funkcie a po
jej ukončení sa stratí
• ako funguje:– vytvorí sa lokálna kópia premennej v zásobníku a vo funkcii sa pracuje
len s ňou– na konci funkcie sa lokálna kópia stráca
príklad: volanie funkcie int A(...) s parametrom 3, ktorý sa vo funkcii zmení na 4
![Page 79: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/79.jpg)
Parametre funkcií - volanie hodnotou
3
zásobník
spustenie programu, volanie main()
volanie A() spustenie A(3)
koniec programu, main()
návrat do main() koniec A()4
3
dátová oblasť
vytvorí sa kópia
![Page 80: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/80.jpg)
Parametre funkcií - volanie odkazom
• predávanie parametrov odkazom neexistuje v C – volanie odkazom by umožnilo meniť parametre v rámci funkcie
– rieši sa pomocou ukazovateľov– ukazovateľ určuje, na ktorom mieste v dátovej pamäti sa má
premenná zmeniť (nemení sa ukazovateľ - adresa)
príklad: volanie funkcie int A(...) s adresou premennej, ktorej hodnota je 3, Vo funkcii sa zmení
hodnota premennej na 4
![Page 81: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/81.jpg)
Parametre funkcií - volanie odkazom
15
zásobník
spustenie programu, volanie main()
volanie A() spustenie A(15)
koniec programu, main()
návrat do main() koniec A()
dátová oblasť
adresa: 15
adresapremennej
34
![Page 82: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/82.jpg)
Procedurálne programovanie:Príklady
![Page 83: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/83.jpg)
Príklad 1
program načíta celé číslo, potom umožní používateľovi v cykle číslo
násobiť dvoma, deliť troma, vypísať číslo - pokým používateľ program
neukončí
![Page 84: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/84.jpg)
#include <stdio.h>
int nasob_2(int x);
int del_3(int x);
int main() {
int i, c;
printf("Zadajte cele cislo: ");
scanf("%d", &i);
do {
printf("\ncislo ma hodnotu: %d\n\n", i);
printf("stlacte N na vynasobie cisla dvoma.\n");
printf("stlacte D na vydelenie cisla troma.\n");
printf("stlacte K na ukoncenie programu.\n");
c = getch();
if (c == 'n' || c == 'N')
i = nasob_2(i);
else if (c == 'd' || c == 'D')
i = del_3(i);
} while (c != 'k' && c != 'K');
return 0;
}
int nasob_2(int x) { return x * 2;}
int del_3(int x) { return x / 3;}
![Page 85: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/85.jpg)
Príklad 2
program vypočíta hodnotu
funkcií p(x) a q(x) pre dané x.
p(x) =p(x-1) + q(x/2)
2
ak x > 1
ak x <= 1
q(x) =q(x-3) + p(x-5)
x/3
ak x > 3
ak x <= 3
![Page 86: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/86.jpg)
#include <stdio.h>
float q(float x);
float p(float x) {
if (x <= 1)
return 2.0;
return (p(x-1) + q(x/2));
}
float q(float x) {
if (x <= 3)
return x / (float) 3.0;
return (q(x-3) * p(x-5));
}int main() { float x;
do { printf("Zadajte realne cislo (konec pri zadani -1.0)\n"); scanf("%f", &x); if (x == -1.0) break; printf("\np(%.3f) = %.3f\n", x, p(x)); printf("q(%.3f) = %.3f\n\n", x, q(x)); } while (1);}
![Page 87: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/87.jpg)
Príklad 3
long faktorial(long n){ if (n <= 0) return 1; else {
}}
#include <stdio.h>
... /* definicia funkcie faktorial */
void main () { int n;
printf("Zadajte cele cislo: "); scanf("%d", &n); printf("%d! = %d\n", n, faktorial(n));}
Faktoriál - iteratívne
int i, f=1;
for(i=1; i<=n; i++) f *= i; return f;
![Page 88: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/88.jpg)
Príklad 4
program opisuje text zo súboru subor.txt na obrazovku s tým, že po vypísaní jednej stránky čaká na
stlačenie klávesy <Enter>
![Page 89: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/89.jpg)
#include <stdio.h>
#define RIADKY_OBR 20
#define MENO "subor.txt"
void vypis(FILE *fr);
int main(void) {
FILE *fr;
if ((fr = fopen(MENO, "r")) == NULL) {
printf("Subor %s nebol otevoreny.\n", MENO);
return 1;
}
vypis(fr);
if (fclose(fr) == EOF)
printf("Subor %s nebol zatvoreny.\n", MENO);
return 0;
}
Úplný funkčný prototyp
Príklad 4
![Page 90: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/90.jpg)
void vypis(FILE *fr) {
int c, pocet = 0;
while ((c = getc(fr)) != EOF) {
putchar(c);
if (c == '\n') {
if (++pocet >= RIADKY_OBR) {
pocet = 0;
while (getchar() != '\n')
;
}
}
}
}
Príklad 4
pokračovanie:
Čaká na odriadkovanie, až
potom vypisuje ďalšiu stránku
![Page 91: Procedur álne programovanie: 4 . prednáška](https://reader035.vdocuments.pub/reader035/viewer/2022062314/56813fe9550346895daadd43/html5/thumbnails/91.jpg)
Deti, poponáhľajte sa pomôcť otcovi
stlačiť Ctrl-Alt-Del!Všetky okná
mi zase zamrzli!