1 / 69

Procedur álne programovanie: 8 . prednáška

Procedur álne programovanie: 8 . prednáška. Gabriela Kosková. Obsah. Rie šenie časti testu Štruktúry a sp ájané zoznamy. Výpis po čtu slov na základe dĺžky. #include <stdio.h> #define SUBOR "beatles.txt" int main() { FILE *f; int akt_dlzka = 0, dlzka, pocet = 0; char c;

cherie
Download Presentation

Procedur álne programovanie: 8 . 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:8. prednáška Gabriela Kosková

  2. Obsah • Riešenie časti testu • Štruktúry a spájané zoznamy

  3. Výpis počtu slov na základe dĺžky #include <stdio.h> #define SUBOR "beatles.txt" int main() { FILE *f; int akt_dlzka = 0, dlzka, pocet = 0; char c; scanf("%d", &dlzka); if((f = fopen(SUBOR, "r")) == NULL) { printf("Subor %s sa nepodarilo otvorit.\n", SUBOR); return 1; } while((c = getc(f)) != EOF) { if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) akt_dlzka++; else { if(akt_dlzka >= 1 && akt_dlzka <= dlzka) pocet++; akt_dlzka = 0; } }

  4. Výpis slov zo zvolehého riadku if(akt_dlzka >= 1 && akt_dlzka <= dlzka) pocet++; printf("Pocet slov: %d", pocet); if(fclose(f) == EOF) printf("Subor %s sa nepodarilo zatvorit.\n", SUBOR); return 0; }

  5. Hodnoty premenných int *Euro, *Dolar, *CZK, *pom; Euro = (int *) malloc(sizeof(int)); Dolar = (int *) malloc(sizeof(int)); CZK = (int *) malloc(sizeof(int)); *Euro = 100; *Dolar = 200; *CZK = 0; *CZK = *Dolar;*Euro = *CZK;*Dolar = *Dolar + 100;pom = Euro; Euro = Dolar;Dolar = pom;*CZK = *Euro; *pom = *CZK + *Euro;pom = NULL; Riešenie na tabuli

  6. Definícia makra (obsah kruhu) #define PI 3.14 #define obsah(r) (PI * (r) * (r))

  7. Vyhodnocovanie logických operátorov #include <stdio.h> int main(void) { int i = 10, j = 5; if ((i %= j) && ++j == 6) printf ("Logicky sucin\n"); printf("i: %d j: %d\n", i, j); return 0; } i: 0 j: 5

  8. Vyhodnocovanie logických operátorov #include <stdio.h> int main(void) { int i = 12, j = 5; if ((i %= j) || ++j == 6) printf ("Logicky sucet\n"); printf("i: %d j: %d\n", i, j); return 0; } Logicky sucet i: 2 j: 5

  9. Procedurálne programovanie: Štrutkúry, uniony a výmenované typy

  10. struct { položka_1; ... položka_n; } Čo je to štruktúra? • štruktúra (struct) je heterogénny dátový typ • heterogénny: je zložený z prvkov rozličných dátových typov (pole je homogénny dátový typ) dá sa definovať piatimi rôznymi spôsobmi

  11. Definícia štruktúry (1) • základný spôsob • štruktúra nie je pomenovaná, • nedá sa inde v progame použiť • dajú sa použiť len definované premenné struct { int vyska; float vaha; } pavol, jan, karol;

  12. Definícia štruktúry (2) • modifikácia základného spôsobu • štruktúra je pomenovaná, • dá sa využiť aj inde v programe struct miery{ int vyska; float vaha; } pavol, jan, karol;

  13. Definícia štruktúry (3) • podobne ako predchádzajúci spôsob • definícia štruktúry a premenných je oddelená od definície premenných (ktoré sa môžu robiť viackrát) struct miery { int vyska; float vaha; }; struct miery pavol; struct miery jan, karol;

  14. Definícia štruktúry (4) • definícia nového typu (typedef) • štruktúra nie je pomenovaná, pomenovaný je typ • typ sa dá použiť na definíciu premenných, pretypovanie... typedef struct { int vyska; float vaha; }MIERY; MIERY pavol, jan, karol; nebolo použité "struct"

  15. Definícia štruktúry (5) • modifikácia predchádzajúceho spôsobu • štruktúry aj typ je pomenovaná (v tomto prípade to nie je potrebné, ale neskôr to budeme potrebovať) typedef struct miery{ int vyska; float vaha; } MIERY; MIERY pavol, jan, karol; odporúča sa pomenovať typ aj štruktúru rovnako, odlíšiť ich len veľkosťou písma

  16. Používanie štruktúr • odporúča sa používať definície typu (4) a (5) • je to prehľadnejšie ("struct" sa použije len raz) typedef struct { int vyska; float vaha; } MIERY; MIERY pavol, jan, karol; typedef struct miery { int vyska; float vaha; } MIERY; MIERY pavol, jan, karol;

  17. často sa používa pole štruktúr: MIERY ludia[100]; ludia[50].vyska = 156; v ANSI C sa dá urobiť Prístup k položkám štruktúry • bodková notácia typedef struct { int vyska; float vaha; } MIERY; MIERY pavol, jan, karol; pavol.vyska = 182; karol.vaha = 62.5; jan.vyska = pavol.vyska; ludia[0] = ludia[50];

  18. takto sa dá použiť štruktúra na to, aby sa dalo naraz skopírovaťcelé pole Pole v štruktúre typedef struct { int pole[10]; }STR_POLE; void main() { STR_POLE a, b; a.pole[0] = 5; b = a; }

  19. p_s = (STUDENT *) malloc(sizeof(STUDENT)); p_s = &s; Štruktúry a ukazovatele • použitie: • štruktúra v dynamickej pamäti • štruktúra vo funkcii *p_s - ukazovateľ naštruktúru, nemá pridelené miesto v pamäti, preto je potrebné alokovať mu pamäť. typedef struct { char meno[30]; int rocnik; }STUDENT; STUDENT s, *p_s; alebo nastaviť ukazovateľ na inú pamäť

  20. STUDENT s; P_STUDENT p_s; p_s = (P_STUDENT *) malloc(sizeof(STUDENT)); s.rocnik = 2; (*p_s).rocnik = 3; p_s->rocnik = 4; Štruktúry a ukazovatele typedef struct { char meno[30]; int rocnik; }STUDENT, *P_STUDENT; definícia typu ukzovateľa na štruktúru prístup k štruktúre pomocou ukazovateľa

  21. Prístup do štruktúry pomocou ukazovateľa STUDENT s, *p_s; s.rocnik = 2; chybné, lebo. má väčšiu prioritu ako *, teda tam, kam ukazuje p_s.rocnik (adesa 3) priraďhodnotu 4 (*p_s).rocnik = 3; *p_s.rocnik = 4; p_s->rocnik = 5;

  22. vyskum.html home.html <html> <head> <title>Vyskum </title> ... <html> <head>...</head> <body> .... tato stranka sa odkazuje na stranku <a href="vyskum.html">vyskum</a> ... <a href="pub.html">publikacie</a> ... <a href="vyucba.html">vyucba</a> ... </body> pub.html <html> <head> <title>Publika </title> ... vyucba.html <a href="vyskum.html">vyskum</a> <html> <head> <title>Vyucba </title> ... <a href="pub.html">publikacie</a> <a href="vyucba.html">vyucba</a> Štruktúry ukazujúce samy na seba: príklad 1 • hypertext • web stránka má odkaz na web stránku (ukazovateľ na rovnaký typ)

  23. AMBULANCIA Štruktúry ukazujúce samy na seba: príklad 2 • pacienti v čakárni u lekára • "Kto je posledný?" • každý človek si pamätá človeka, ktorý je pred ním (ukazovateľ na ten istý typ)

  24. typedef struct { int hodnota; struct POLOZKA *p_dalsi; }POLOZKA; Štruktúry ukazujúce samy na seba typedef structpolozka { int hodnota; struct polozka *p_dalsi; }POLOZKA; odkaz na samého seba (na takú istú štruktúru) aj štruktúra, aj typ musia byť pomenované chyba: v čase, keď sa definujem p_dalsi, POLOZKA ešte nie je známa

  25. typedef struct clovek { char meno[30]; int rocnik; struct clovek *dalsi; }CLOVEK; 1. položka ... n. položka ukazovateľ Spájaný zoznam • dynanamický zoznam prvkov : • v pamäti je práve toľko prvkov, koľko je potreba • dá sa pridávať na ktorékoľvek miesto v zozname ukazuje na ten istý typ

  26. q  q  p  Jurko 3 Miško 2 Janko 1 Spájaný zoznam typedef struct clovek { char meno[30]; int rocnik; struct clovek *dalsi; }CLOVEK; CLOVEK *p, *q; q = (CLOVEK *) malloc(sizeof(CLOVEK)); q->meno = Jurko; q->rocnik = 3; q->dalsi = NULL; p->dalsi->dalsi = q; p = (CLOVEK *) malloc(sizeof(CLOVEK)); p->meno = Janko; p->rocnik = 1; p->dalsi = NULL; q = (CLOVEK *) malloc(sizeof(CLOVEK)); q->meno = Misko; q->rocnik = 2; q->dalsi = NULL; p->dalsi = q;

  27. 1 2 3 4 5 6 7 Spájaný zoznam: príklad • Vtvorí sa spájaný zoznam s hodnotami 1...n, potom sa vymažú všetky prvky, ktoré sú deliteľné 3. typedef structprvok { int hodnota; struct prvok *dalsi; } PRVOK;

  28. p_akt p_prv  p_pred 1 #include <stdio.h> #include <stdlib.h> typedef structprvok { int hodnota; struct prvok *dalsi; } PRVOK; void main() { int i, n; PRVOK *p_prv, *p_akt, *p_pred; printf("Zadaj pocet prvkov zoznamu: "); scanf("%d", &n); if((p_prv = (PRVOK *) malloc(sizeof(PRVOK))) == NULL){ printf("Malo pamate.\n") return; } p_prv->hodnota = 1;

  29. 1 n ... p_akt = p_prv; for(i = 2; i < n; i++) { if(p_akt->dalsi = (PRVOK *) malloc(sizeof(PRVOK))) == NULL) { printf("Malo pamate.\n") break; } p_akt = p_akt->dalsi; p_akt->hodnota = i; } p_akt->dalsi = NULL; p_akt p_prv  p_pred 2 for(p_pred = p_akt = p_prv; p_akt != NULL; p_pred = p_akt, p_akt = p_akt->dalsi) { if(p_akt->hodnota % 3 == 0) { p_pred->dalsi = p_akt->dalsi; free((void *) p_akt); p_akt = p_pred; } } }

  30. Štruktúra v inej štruktúre • štruktúra, ktorá je v inej štruktúre musí byť definovaná skôr ako je do inej štruktúry uložená (vhniezdená štruktúra) • predtým sme mali len odkaz na štruktúru typedef struct { char meno[30]; ADRESA adresa; float plat; }OSOBA; typedef struct { char ulica[30]; int cislo; }ADRESA; príklad: vypísať adresu zamestnanca s najvyšším platom (OSOBA ludia[100])

  31. int i, kto = 0; float max = 0.0, pom; OSOBA ludia[100]; ... /* inicializacia */ for (i = 0; i < 100; i++) { if((pom = ludia[i].plat) > max) { max = pom; kto = i; } } printf("Zamestnanec s najvyssim platom byva: %s %d", ludia[kto].adresa.ulica, ludia[kto].adresa.cislo); Príklad: štruktúra v inej štruktúre typedef struct { char ulica[30]; int cislo; }ADRESA; typedef struct { char meno[30]; ADRESA adresa; float plat; }OSOBA;

  32. float max = ludia[0].plat, pom; OSOBA ludia[100], *p_kto, *p_pom; ... /* inicializacia */ for (p_pom = p_kto = ludia; p_pom < ludia + 100; p_pom++) { if ((p_pom->plat) > max) { p_kto = p_pom; max = p_pom->plat; } } printf("Zamestnanec s najvyssim platom byva: %s %d", p_kto->adresa.ulica, p_kto->adresa.cislo); Príklad: štruktúra v inej štruktúre - cez ukazovateľe typedef struct { char ulica[30]; int cislo; }ADRESA; typedef struct { char meno[30]; ADRESA adresa; float plat; }OSOBA;

  33. Alokácia pamäte pre jedotlivé položky štruktúry • položky obsadzujú pamäť zhora dole a zľava doprava • pre p v poradí: c i j k d • položky sú väčšinou zarovnávané na párne adresy • za položkou c je väčšinou 1 prázdny Byte • štruktúra väčšinou končí na párnej adrese • za položkou d - 1 volný Byte typedef struct { char c; int i, j, k; char d; } POKUS; POKUS p; na zistenie veľkosti:sizeof(p);

  34. Šturktúry a funkcie • K&R verzia jazyka C: • parameter: ukazovateľ na štruktúru • návratový typ: ukazovateľ na štruktúru • ANSI C: • parameter: ukazovateľ na štruktúru aj samotná štruktúra • návratový typ: ukazovateľ na štruktúru aj samotná štruktúra

  35. ak sú štrutúry veľké, nevýhodné, lebo sa vytvárajú lokálne kópie (časovo aj pamäťovo náročné)  vhodné používať ukazovatele Príklad: šturktúry a funkcie • sčítanie komplexných čísel typedef struct { double re, im; } KOMP; KOMPsucet(KOMP a, KOMP b) { KOMP c; c.re = a.re + b.re; c.im = a.im + b.im; return c; } void main() { KOMP x, y, z; x.re = 1.4; x.im = 3.2; y = x; z = sucet(x, y); }

  36. Príklad: šturktúry a funkcie -pomocou ukazovateľov • sčítanie komplexných čísel typedef struct { double re, im; } KOMP; voidsucet(KOMP *a, KOMP *b, KOMP *c) { c->re = a->re + b->re; c->im = a->im + b->im; } void main() { KOMP x, y, z; x.re = 1.4; x.im = 3.2; y = x; sucet(&x, &y, &z); }

  37. STUDENT *vytvor1(void) { STUDENT p; p = (STUDENT *) malloc(sizeof(STUDENT)); if (p = NULL) printf("Malo pamate.\n"); return p; } void vytvor2(STUDENT **p) { p = (STUDENT *) malloc(sizeof(STUDENT)); if (p = NULL) printf("Malo pamate.\n"); } Príklad: dynamické vytváranie štruktúry vo funkciách typedef struct { char meno[30]; int rocnik; } STUDENT; vracia štruktúru ako ukazovateľ vracia štruktúru cez parameter

  38. void main() { STUDENT s, *p_s1, *p_s2; p_s1 = vytvor1(); vytvor2(&p_s2); s.rocnik = p_s1->rocnik = 1; nastav(&s, "Martin", 1); nastav(p_s1, "Peter", 2); nastav(p_s2, "Michal", 3); } Príklad: dynamické vytváranie štruktúry vo funkciách void nastav(STUDENT *p, char *meno, int rok) { p->rocnik = rok; strcpy(p->meno, meno); }

  39. Inicializácia štruktúr typedef struct { char meno[30]; int rocnik; } STUDENT; STUDENT s = { "Janko", 3 }; STUDENT studenti[] = { { "Misko", 3 }, { "Jurko", 2 } }; pocet = sizeof(studenti) / sizeof(STUDENT);

  40. Vymenované typy • enumerate type - zoznam symbolických konštánt, ktoré sú zvyčajne vzájomne závislé • zvyšuje čitateľnosť programu tu nie je bodkočiarka typedef enum { MODRA, CERVENA, ZELENA, ZLTA } FARBY; FARBY c, d; c = MODRA; d = CERVENA; ak nepriradíme konštatnám hodnoty, implicitne sú 0, 1, 2, ...

  41. BOOLEAN dobre; Príklad: boolovské hodnoty typedef enum { FALSE, TRUE } BOOLEAN; if(isdigit(c) == FALSE) ... nie je nutné ani definovať premennú premenná môže byť definovaná

  42. Explicitná a implicitná inicializácia • explicitná inicializácia: • zoradiť podľa veľkosti • inicializujeme všetky prvky poľa typedef enum { MODRA = 0, CERVENA = 4, ZELENA = 2, ZLTA } FARBY; najhoršie možné: čiastočne explicitné, čiastočne implicitné (ZLTA bude mať hodnotu 3)

  43. Výpis mena položky typedef enum { MODRA, CERVENA, ZELENA, ZLTA } FARBY; ... c = MODRA; chyba! printf("Farba: %s \n", c); printf("Farba: %d \n", (int) c); s pretypovaním: výpis hodnôt switch (c) { case MODRA: printf("Modra farba.\n"); break; ... } výpis mien položiek: pomocou switch

  44. Výpis mena položky: pomocou poľa typedef enum { MODRA, CERVENA, ZELENA, ZLTA } FARBY; FARBY farba = MODRA; char *nazvy[]= { "Modra", "Cervena", "Zelena", "Zlta" }; printf("Farba: %s \n", nazvy[farba]); len pre neinicializované vymenované typy

  45. a.c = '#'; p_a->i = 1; a.f = 2.3; premazávajú sa hodnoty Uniony • dátový typ • vyhradí sa pamäť pre najväčšiu položku • všetky položky sa prekrývajú typedef union { char c; int i; float f; } ZIF; ZIF a, *p_a = &a; Union neposkytuje informáciu o typu prvku, ktorý bol naposledy do neho uložený! vyhradí sa pamäť o veľkosti najväčšieho prvku

  46. Union vložený do štruktúry typedef enum { ZNAK, CELE, REALNE } TYP; typedef union { char c; int i; float f; } ZIF; typedef struct { TYP typ; ZIF polozka; } ZN_INT_FL; vymenovaný typ: slúži na rozlíšenie typov union: umožňuje uchovávať znak, celé a reálne číslo štruktúra: obsahuje informáciu o type položky a samotnú položku

  47. #include<stdio.h> #include<stdlib.h> #define MAXR 5 #define MAXS ('E' - 'A') #define NPRIKAZ 10 typedef enum { VYR, CIS } TYP; typedef struct { char oper; double l_operand; double r_operand; } VYRAZ; typedef struct { TYP typ; union { VYRAZ vyraz; double cislo; } hodnota; } BUNKA;

  48. void inicializuj(BUNKA excel[][MAXS], int r); void priradit_vyraz(BUNKA excel[][MAXS], int r, int i, int j, char prikaz[]); double vypocitaj(VYRAZ v); void vypis_hodnoty(BUNKA excel[][MAXS], int r); void vypis_vyrazy(BUNKA excel[][MAXS], int r);

  49. void main() { BUNKA excel[MAXR][MAXS]; int i=0, j=0; char c; char prikaz[NPRIKAZ]; inicializuj(excel, MAXR); do { printf("\n*** TABULKOVY PROCESOR ***\n"); printf("= priradene: format =o(c1,c2)\n"); printf("p presun kurzora: format prs\n"); printf("h vypis hodnot \nv vypis vyrazov\n"); printf("k koniec\n"); printf("\nKurzor: %c%d\n\n", i+'A', j); gets(prikaz);

  50. switch (tolower(prikaz[0])) { case '=': priradit_vyraz(excel, MAXR, i, j, prikaz); break; case 'p': if (sscanf(prikaz+1, "%c %d", &c, &j) != 2) { printf("Nespravny format vstupu.\n"); break; } if ((i = toupper(c)-'A') > MAXR) i = MAXR - 1; if (i < 0) i = 0; if (j > MAXS) j = MAXS - 1; if (j < 0) j = 0; break; case 'h': vypis_hodnoty(excel, MAXR); break; case 'v': vypis_vyrazy(excel, MAXR); break; case 'k': break; default: break; } } while (prikaz[0] != 'k'); }

More Related