1 / 91

Procedur álne programovanie: 4 . prednáška

Procedur álne programovanie: 4 . prednáška. Gabriela Kosková. Obsah. opakovanie ( 4 príklady) preprocesor pr íklady ( 4 ) funkcie a práca s pamäťou pr íklady (4). Procedur álne programovanie: Pr ác a so súborom - opakovanie v pr íkladoch. P r íklad 1.

samson
Télécharger la présentation

Procedur álne programovanie: 4 . prednáška

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  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 • príklady (4)

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

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

  5. if(fclose(fr) == EOF) printf("Nepodarilo sa zatvorit suobor.\n"); #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; }

  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. #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; }

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

  9. 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 #errortext

  14. Konštrukcie pre preprocesor • podmienený preklad v závislosti od toho, či je makro definované, alebo nedefinované #ifdefmeno_makra #elif #else #endif • podmienený preklad v závislosti od toho, či je makro nedefinované, alebo definované #ifndefmeno_makra #elif #else #endif

  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 • za hodnotou nie je ; • medzi menom konštanty a jej hodnotou nie je = #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.

  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 • pri použití nie je makro ukončené bodkočiarkou: #define ERROR { printf("Chyba v datach.\n"); } 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. definícia makra #define je_velke(c) ((c) >= 'A' && (c) <= 'Z') v zdrojovom súbore ch = je_velke(ch) ? ch + ('a' - 'A') : ch; rozvinie sa ch = ((ch) >= 'A' && (ch) <= 'Z') ? ch + ('a'-'A') : ch; 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)

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

  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 • ladiace časti - napr. pomocné výpisy • program • trvalá časť • voliteľná časť (napr. pri ladení, alebo ak je argumentom programu nejaký prepínač)

  30. ak pri testovaní nechcete prekladať časť programu, namiesto /* */ (problém by robili vhniezdené komentáre) #if 0 cast programu, co ma byt vynechana #endif 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

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

  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_LADENIA2 #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

  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. 2+3*2+3*2+3 = 17 (nie 125) 2*3+1*2*3+1*2*3+1 = 19, (nie 343) 5^3 = 17 7^3 = 19 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

  39. Príklad 3 program zistí, či bola načítaná nula - pomocou makracitaj_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 #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; } #define LADENIE #ifdef LADENIE printf("\n(y: %d, nasobok: %d)\n", y, nasobok); #endif

  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íciepo 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

More Related