Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Procedurálne programovanie: 4. prednáška

Podobné prezentace


Prezentace na téma: "Procedurálne programovanie: 4. prednáška"— Transkript prezentace:

1 Procedurálne programovanie: 4. prednáška
Gabriela Kosková

2 Obsah opakovanie (4 príklady) preprocesor príklady (4)
funkcie a práca s pamäťou

3 Procedurálne programovanie: Práca so súborom - opakovanie v príkladoch

4 Príklad je na vrátenie znaku na vstup.
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.

5 #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)) != '$') } 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");

6 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

7 if (fclose(fw) == EOF) #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");

8 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"); Pred ukončením programu treba zatvoriť všetky otvorené súbory

9 Kontrola zatvorenia dvoch súborov
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í

10 Procedurálne programovanie: Preprocesor

11 Č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 #

12 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

13 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

14 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

15 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

16 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)

17 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 =

18 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; }

19 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

20 Kedy sa nerozvinie makro
makro sa nerozvinie, ak je uzatvorené v úvodzovkách #define MENO "Katka" ... printf("Volam sa MENO"); printf("Volam sa %s", MENO); vypíše sa: Volam sa MENO vypíše sa: Volam sa Katka

21 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

22 Makro ako skrytá časť programu
#define ERROR { printf("Chyba v datach.\n"); } pri použití nie je makro ukončené bodkočiarkou: if (x == 0) ERROR else y = y / x;

23 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

24 Makrá s parametrami nazývajú sa vkladané funkcie - rozvitie makra znamená, že sa meno makra nahradí jeho telom #define je_velke(c) ((c) >= 'A' && (c) <= 'Z') definícia makra zátvorka, v ktorej sú argumenty funkcie - hneď za názvom makra (bez medzery) ch = je_velke(ch) ? ch + ('a' - 'A') : ch; v zdrojovom súbore ch = ((ch) >= 'A' && (ch) <= 'Z') ? ch + ('a'-'A') : ch; rozvinie sa

25 Makrá s parametrami telo makra - uzavrieť do zátvoriek, inak môžu nastať chyby, napr.: #define sqrt(x) x * x ... sqrt(f + g); f + g * f + g; po rozvinutí makra #define sqrt(x) ((x) * (x)) ... sqrt(f + g); správne ((f + g) * (f + g)); po rozvinutí makra

26 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

27 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

28 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"

29 Podmienený preklad u väčších programov program
ladiace časti - napr. pomocné výpisy program trvalá časť voliteľná časť (napr. pri ladení, alebo ak je argumentom programu nejaký prepínač)

30 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)

31 Riadenie prekladu hodnotou konštantného makra
#define PCAT 1 #if PCAT #include <conio.h> #else #include <stdio.h> #endif ak je program závislý na konkrétnom počítači ak na PC/AT - definujeme PCAT na 1, inak na 0

32 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 #ifndef PCAT ak nie je definovaná konštanta zrušenie definície makra #undef PCAT

33 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)

34 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

35 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 najprv musíme prebrať funkcie...

36 Procedurálne programovanie: Príklady

37 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; }

38 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; } 7^3 = 19 2*3+1*2*3+1*2*3+1 = 19, (nie 343) 5^3 = 17 2+3*2+3*2+3 = 17 (nie 125) ((x) * (x) * (x)) 3^3 = 9 2^3 = 8

39 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; }

40 program vynásobí dve čísla len pomocou sčitovania, v cykle použijeme ladiace výpisy
Príklad 4 #define LADENIE #ifdef LADENIE printf("\n(y: %d, nasobok: %d)\n", y, nasobok); #endif #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;

41 Procedurálne programovanie: Funkcie a práca s pamäťou

42 Funkcie a práca s pamäťou
lokálne a globálne premenné pamäť funkcie

43 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

44 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()

45 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.

46 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!

47 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á

48 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

49 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

50 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

51 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

52 Funkcie jazyk C je založený na funkciách spracovanie programu
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)

53 return h; - funkcia vráti hodnotu h
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); } return h; - funkcia vráti hodnotu h x = max(10 * i, j - 15);

54 Funkcia bez parametrov
definícia funkcie: volanie funkcie: int scitaj() { int a, b; scanf("%d %d", &a, &b); return (a + b); } j = scitaj();

55 Procedúry a dátový typ void
formálne procedúry neexistujú, dá sa to obísť: 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(); čakanie na stlačenie klávesy (void) getchar(); čitateľnejšie, niektoré prekladače to vyžadujú

56 Procedúry a dátový typ void
funkcia sa definuje ako funkcia vracajúca typ void (nič), napr. - volanie procedúry (funkcie): void vypis_int(int i) { printf("%d", i); } vypis_int(a + b);

57 Príklad 1: použitie funkcie v programe
maximum z dvoch čísel 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;

58 Príklad 2: použitie funkcie v programe
maximum z dvoch čísel - volanie funkcie viackrát #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;

59 Rekurzia :-) vysvetlenie slova rekurzia vo výkladovom slovníku:
- rekurzia: viď rekurzia funkcia, ktorá volá samu seba (väčšinou s inými parametrami)

60 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)); }

61 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)) 2 6 fakt(2): (2 <= 0) neplatí  return(n * fakt(n-1)) 2 * fakt(1)) 1 2 fakt(1): (1 <= 0) neplatí  return(n * fakt(n-1)) 1 1 * fakt(0)) 1 fakt(0): (0 <= 0) platí  return(1) 1

62 Fibonacciho čísla 0, 1, 1, 2, 3, 5, 8, 13, 25, ... (čísla v postupnosti sú súčtom dvoch predošlých čísel) f(1) = 0 f(2) = 1 f(n) = f(n-1) + f(n-2) Pôvodný Fibonnaciho problém (1202) - ako sa môžu králiky rozmnožovať v ideálnych podmienkach

63 Fibonacciho králiky Predpoklady: Hádanka, ktrorú Fibonacci položil:
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?

64 na konci prvého mesiaca sa pária, stále ešte len jeden pár
Fibonacciho králiky 1 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 na konci tretieho mesiaca sa samičke s bielym chvostíkom narodí nový pár na konci druhého mesiaca sa samičke s bielym chvostíkom narodí nový pár na konci prvého mesiaca sa pária, stále ešte len jeden pár 2 3 4 5

65 Fibonacciho čísla lastúra štvorce špirály semienka kvetov

66 Fibonacciho čísla: rekurzívne
6 4 5 3 2 1 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

67 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)

68 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

69 Funkcie vracajúce int a iné typy
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)

70 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) {

71 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: deklaráciou návratového typu a mena pomocou funkčného prototypu

72 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é

73 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

74 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

75 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

76 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

77 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); } hodnota 4.5 bude pretypovaná na int - oreže sa a k bude mať hodnotu 4 int k; k = konverzia(4.5);

78 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 

79 Parametre funkcií - volanie hodnotou
dátová oblasť spustenie programu, volanie main() 3 vytvorí sa kópia volanie A() spustenie A(3) 3 4 návrat do main() koniec A() koniec programu, main() zásobník

80 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 

81 Parametre funkcií - volanie odkazom
dátová oblasť spustenie programu, volanie main() adresa: 4 3 adresa premennej volanie A() spustenie A(15) 15 návrat do main() koniec A() koniec programu, main() zásobník

82 Procedurálne programovanie: Príklady

83 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čí

84 #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;

85 Príklad 2 program vypočíta hodnotu funkcií p(x) a q(x) pre dané x.
p(x-1) + q(x/2) ak x > 1 p(x) = ak x <= 1 2 q(x-3) + p(x-5) ak x > 3 q(x) = ak x <= 3 x/3

86 #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); }

87 Faktoriál - iteratívne
Príklad 3 Faktoriál - iteratívne long faktorial(long n) { if (n <= 0) return 1; else { } int i, f=1; for(i=1; i<=n; i++) f *= i; return f; #include <stdio.h> ... /* definicia funkcie faktorial */ void main () { int n; printf("Zadajte cele cislo: "); scanf("%d", &n); printf("%d! = %d\n", n, faktorial(n)); }

88 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>

89 Úplný funkčný prototyp
Príklad 4 #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

90 Čaká na odriadkovanie, až potom vypisuje ďalšiu stránku
Príklad 4 pokračovanie: 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') ; } Čaká na odriadkovanie, až potom vypisuje ďalšiu stránku

91 Deti, poponáhľajte sa pomôcť otcovi stlačiť Ctrl-Alt-Del!
Všetky okná mi zase zamrzli!


Stáhnout ppt "Procedurálne programovanie: 4. prednáška"

Podobné prezentace


Reklamy Google