1 / 82

C/C++ a Pascal

C/C++ a Pascal. Ing . Peter Pi štek , C E ng. Obsah. Opakovanie z minulého stretnutia Ukazovatele (Pointre) Jednorozmerné polia Viacrozmerné polia Reťazce Dynamické štruktúry. Opakovanie. Základné konštrukcie jazyka Základné údajové šruktúry Funkcie Cykly a rekurzia

nadine
Télécharger la présentation

C/C++ a Pascal

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. C/C++ a Pascal Ing. Peter Pištek, CEng.

  2. Obsah • Opakovanie z minulého stretnutia • Ukazovatele (Pointre) • Jednorozmerné polia • Viacrozmerné polia • Reťazce • Dynamické štruktúry

  3. Opakovanie • Základné konštrukcie jazyka • Základné údajové šruktúry • Funkcie • Cykly a rekurzia • Práca so súbormi • Struct

  4. Opakovanie • C je casesensitive jazyk • Prototypovanie funkcií • Pri načítavaní scanf (“parametre“, &premenna) • Rovný (==), rôzny (!=), AND ( &&), OR (||), NOT (!) • Zátvorkovanie podmienok • Vo vetvách switchu treba používať príkaz break • Cyklus for môže byť nekonečný • Práca so súbormi (princípe sa pridáva pred názov funkcie „f“ a do argumentov sa pridáva súbor)

  5. Opakovanie • Príkaz fflush okamžite uloží obsah buffra do súboru • Radšej používať feof() ako konštantu EOF • EOLN nie je, treba hľadať \n • stdin, stdout, stderr • Definovanie konštánt - #define MAX 100 • typedef – definovanie vlastných typov • Record == struct

  6. Mini opakovanie switch(getchar()) { case 'a' : putchar('a'); case 'b' : putchar('b'); case 'c' : putchar('c'); default : putchar('x'); } x, y: double; printf("Zadajte2realnecisla: "); scanf("%lf %lf", x, y); printf("%.2lf\n", (x > y) ? x : y); for (i = 1,i <= n,i++) { for (j = 2, j <=i,j++) printf("%d ", &j); putchar('\n'); }

  7. Pointre • Ukazovatele na premenné • Ich obsahom je adresa pamäte • Štandardne premenné sú premenné v zásobníku, pointre ukazujú do haldy • p: ukazovateľ, *p: hodnota, na ktorú ukazuje • V deklarácií je definovaný pomocou “*“ (int*p) • Treba vždy inicializovať (implicitne-explicitne) • int*p1=1, *p2; • p2=p1; p2=2;

  8. Pointre – adresácie a hodnoty • Klasická premenná int i, pointer int *p • &i – adresapremennej p – adresapointra • i – hodnotapremennej *p – hodnota pointra • *p=iint*p=&i (deklarovanie inicializacia) • Pri debuggingu môžete používať %p (printf,...) • NIL Pascal == NULL C (v stdio.h) • Nepoužívajte konverziu ukazovateľov • char*p_cint *p_i • p_c=p_ip_c=(char *)p_i

  9. Pointre – práca v pamäti pamäť pamäť 7 7 i: 28 i: 28 *p_i: 30 25 30 25 p_i: 73 30 73 28 30

  10. Pointre - inicializácia - správne p_i = &i; -chyba: (i + 3) nie je premenná p_i = &(i + 3); -chyba: konštanta nemá adresu p_i = &15; p_i = 15; - chyba: priraďovanie absolútnej adresy -chyba: do i priradíme obsah p_i i = p_i; -chyba: priraďovanie adresy i = & p_i; -správne, p_i bol inicializovaný p_i = &i;*p_i = 4; *p_i = 4; Najčastejšia chyba, neinicializovaný smerník!

  11. Pointre a parametre funkcií • Pri viacerých návratových hodnotách z funkcie voidvymen(int*p_x, int*p_y) { intpom; pom = *p_x; *p_x = *p_y; *p_y = pom; } • volanie funkcie:vymen(&i, &j) • vymen(i,j); • vymen(*i, *j);

  12. Generický pointer • void*p • Neukazuje na žiadny konkrétny typ • Nezabúdať na pretypovanie voidvymen(void**p_x, void**p_y) { void *p; p = *p_x; *p_x = *p_y; *p_y = p; } inti; float f; void*p_void = &i; *(int *) p_void = 2; p_void = &f; *(float *) p_void = 3.5; char c = 'a', *p_c = &c, d = 'b', *p_d = &d; vymen((void *) &p_c, (void *) &p_d);

  13. Pointre - Príklady definícií -i je typu int int i; -y je ukazovateľ na typ float float *y; -z je funkcia vracajúca ukazovateľ na double double *z(); -v je ukazovateľ na funkciu vracajúcu int int (*v)(); -v je ukazovateľ na funkciu vracajúcu ukazovateľ na int int *(*v)();

  14. Pointre – čítanie definícií Nájdeme identifikátor, od neho čítame doprava pokým nenarazíme na samotnú pravú zátvorku ")". Vraciame sa k zodpovedajúcej ľavej zátvorke. Potom pokračujeme doprava (preskakujeme prečítané) Ak narazíme na ";" , vraciame sa na najľavejšie spracované miesto v čítame doľava pointer na funkciu vracajúcu - v je * int * (*v) () int *(*v)(); pointer na int

  15. Pointre – použitie typedef • Vhodné najmä pri zložitejších typov • int*p_i, **p_p_i; • typedefint *P_INT; • typedef P_INT *P_P_INT • P_INT p_i; P_P_INT p_p_i;

  16. Pointre – sizeof() • Vracia veľkosť dátového typu v Bytoch (napr. zistenie rozsahu pre int) • Pri určovaní veľkostí polí • int*p = 10 p+1=12 (sizeof (int)==2) • Porovnanie ukazovateľov – ako pri bežných premenných. • Len keď sú rovnakého typu, ukazujú na ten istý úsek pamäte • Aritmetika – súčet/rozdiel ukazovateľa a celého čísla

  17. Pointre – dynamické alokovanie • Životnosť od alokovania až po uvoľnenie z pamäte • stdlib.h (občas alloc.h) • void*malloc (unsigned int) – vracia adresu prvého alokovaného prvku a parameter je počet Bytov. Chybový návrat - NULL int* p_i; if((p_i = (int *) malloc(1000)) == NULL) { printf("Nepodarilosapridelitpamat\n"); exit; }

  18. Pointre – uvoľnenie pamäte • Nepotrebnú pamäť je vhodnú okamžite uvoľnovať • voidfree (void*) • po uvoľnení pamäte priradiť pointru NULL

  19. Pointre – calloc • void*calloc(unsignedint) • To isté čo malloc, len automaticky inicializuje Byty na 0 int *alokuj(int n) { return ((int *) malloc(n * sizeof(int))); } voidsucin(int *p, int n, intsucin) { inti; for (i = 0; i < n; i++) sucin *= *(p + i); }

  20. Jednorozmerné polia Pascal X: array[0..9] of integer; #defineN 10 int x[N], y[N+1], z[N*2]; • x má 10 prvkov (0..9), y má 11 prvkov (0..10), z má 20 prvkov (0..19) • Inicializácia v definícií – int x [3]={1,2,3}; • Pole ako parameter funkcie – void funkcia (int pole[]) • Viacrozmerné polia – int x [5][4][5][7]; • Prístup k prvkom poľa ?

  21. Polia a pointre • TYP x[N]; definícia statického poľa • TYP *p_x; definícia smerníka • xa p_x sú smerníky na typ TYP • x jekonštantný smerník jeho hodnota sa nedá meniť • x je adresa začiatku bloku pamäti alokovaného pre statické pole. • p_xje premenná s neurčenou počiatočnou hodnotou, alokuje pamäť iba pre seba

  22. Polia a pointre int*p; p = (int *) malloc(4 * sizeof(int)); *pje smerník nablokpamätialokovanej pomocou funkcie malloc() p je dynamické pole, ktoré vzniká za behu programu • platí: • p[0] == *p • p[1] == *(p + 1) • p[2] == *(p + 2) • p[3] == *(p + 3) int x[4] x + i == &x[i] *(x + i) == x[i] • &x[0] == &*(x + 0) == x • &x[i] == &*(x + i) == (x + i)

  23. Polia a pointre • int x[1], *p_x • p_x=x (OK) x=p_x (ZLE) • void *realloc (void *pole, unsignetint size) • Zväčší alebo vytvorí nové pole a skopíruje tam hodnoty z pôvodného poľa

  24. Pole ako parameter funkcie • int maximum(int pole[], int n) – n reprezentuje veľkosť poľa, vo funkcií nevieme aká je veľkosť poľa • int pole[] je ekvivalentné int*pole int x[10]; max = maximum(&x[2], 5); voidinit(double **p_f) { double *a; inti; a = (double *) malloc(5 *sizeof(double); *p_f = a; } voidmain() { double *p_d; init(&p_d); }

  25. Pole ukazovateľov na funkcie • typedefvoid (* P_FNC)(); • P_FNC funkcie[5] = {file, edit, search, compile, run}; • funkcia[1]();

  26. Viacrozmerné polia • Základné deklarácie • int x[5][4] • typedefint DVA[5][4]; • DVA d • typedefint JEDEN [5] • typedef JEDEN DVA[4] • DVA d • x[i][j] i-riadok, j-stĺpec, x-ukazovateľ na dvojrozmerné pole, x[i] – ukazovateľ na riadok

  27. Viacrozmerné polia • x a x[0] – tá istá adresa len iného typu • Plno fínt s adresáciami – pristupujte k tomu ako v Pascale a všetko bude dobre • &x[i][j] == x[i] + j == *(x + i) + j • adresapremennej • x[i][j] == *(x[i] + j) == *(*(x + i) + j) • hodnotapremennej

  28. Viacrozmerné polia - definície • Statické dvojrozmerné pole intxa[2][3] • Pole ukazovateľov int*xb[2] • Ukazovateľ na pole int (*xc)[3] • Ukazovateľ na ukazovateľint **xd • Najskôr sa alokujú riadky potom jednotlivé stĺpce

  29. Viacrozmerné polia - výhody • xa (intxa[2][3]): pamäťovo najvýhodnejšie • xb(int *xb[2]): naviac pamäť pre 2 ukazovatele (počet riadkov xb[0], xb[1]) • xc(int (*xc)[3]): naviacpamäť pre 1 ukazovateľ na typ int: xc • xd(int **xd): naviac 1 ukazovateľ pre xd a 2 ukazovatele na riadky (xd[0], xd[1]) • xa a xc – pravouhlé polia • xb a xd – nepravidelené polia

  30. Viacrozmerné polia • Podobné ako jednorozmerné polia • Odlišnosť – prvá dimenzia musí byť prázdna, druhá musí byť uvedená • Len pravouhlé polia • Inicializácia • double f[3] = {1.5, 3.0, 7.6 }; • double f[] = {1.5, 3.0, 7.6 }; • double f[3] = {1.5, 3.0 }; • double f[3] = {1.5, 3.0, 7.6, 3.8 }; ZLE • pri dvojrozmerných – musí byť uvedený počet stĺpcov

  31. Reťazce • Poliatypu char • Ukončené sú vždy \0 – ukončovací znak • Ak by chýbal tak číta reťazec až kým nenarazí naň niekde v pamäti char c [4]=“ahoj” – chyba char c [5]=“ahoj” – ok scanf (“%s”,c) – tunemusí byť & %10s – načíta 10 znakov char s[11]; for(i = 0; i < 11-1; i++) s[i] = '*'; s[10-1] = '\0';

  32. Reťazce • char s[] = "abrakadabra"; • char*s; • s = (char *) malloc(6); • char s[10]; • s = "ahoj"; • Dynamický reťazec sa nedá inicializovať (scanf,strcpy)

  33. Reťazce • Dynamický reťazec sa nedá inicializovať (scanf,strcpy) • Nulový reťazec • NULL – neukazuje na žiadne miesto v pamäti • \0 – má na nultom znaku \0 • “x” a ‘x’ je rozdiel • “x” – reťazec s jedným znakom a je ukončený \0 • ‘x’ – je jeden znak

  34. Reťazce – čítanie z klávesnice • scanf vynecháva biele znaky a číta po prvý biely znak (“ ahoj Eva“ -> “ahoj”) • scanf (“%c”,s) by tú medzeru zvládlo – iné správanie ako scanf(“%1s”,s) • scanf (“%s”,s); • Reťazec = pole -> práca s reťazcom je rovnaká ako práca s poľom • Pri práci so statickým reťazcom nezabúdať na \0

  35. Práca s reťazcami • <string.h> • intstrlen(char *s); • char *strcpy(char *s1, char *s2); • char *strcat(char *s1, char *s2); • char *strchr(char *s, char c); • intstrcmp(char *s1, char *s2); • char *strstr(char *s1, char *s2); • char *strncpy(char *s1, char *s2, int max); • char *strrchr(char *s, char c); • intatoi(char *s); • longatol(char *s); • floatatof(char *s);

  36. Práca s reťazcami • char *gets(char *s); (fgets) • intputs(char *s); (fputs) • sprintf – vypisuje do reťazca (fprintf) • sscanf – číta z reťazca (fscanf) • char *p_text[4]; • p_text[0] = "prvy"; • p_text[1] = "druhy"; • p_text[2] = (char*) malloc(6); • strcpy(p_text[2], "treti"); • p_text[3] = "stvrty";

  37. Štruktúry typedefstructmiery{ intvyska; float vaha; } MIERY; MIERY pavol, jan, peter; TBookRec = Record Title, Author, ISBN : String; Price : Real; End; Kniha: TBookRec typedefstruct { intvyska; float vaha; }MIERY; MIERY pavol,jan, peter; struct{ intvyska[20]; float vaha; } peter,pavol,jan; struct miery { intvyska; float vaha; }; struct mierypeter; structmiery{ intvyska; float vaha; } peter,pavol,jan; Prisupnapr. peter.vyska[1]=198;

  38. Priradenie celého poľa naraz typedefstruct pole { int pole[10]; }STR_POLE; void main() { STR_POLE a, b; a.pole[0] = 5; b = a; }

  39. Štruktúry a pointre typedefstruct { char meno[30]; introcnik; }STUDENT; STUDENT s, *p_s; p_s = (STUDENT *) malloc(sizeof(STUDENT)); p_s = &s; (*p_s).rocnik=4 p_s->rocnik=4

  40. Dynamické štruktúry typedefstructpolozka { //ok int hodnota; structpolozka *p_dalsi; }POLOZKA; typedefstruct { //zle int hodnota; structPOLOZKA *p_dalsi; }POLOZKA;

  41. Spájaný jednosmerný zoznam typedefstructpolozka { int hodnota; structpolozka *p_dalsi; }POLOZKA; • Je nutné si pamätať prvý prvok zoznamu (!) • Každý prvok ukazuje na nasledujúci prvok • Posledný prvok ukazuje na NULL

  42. Spájaný jednosmerný zoznam typedefstructclovek { char meno[30]; introcnik; structclovek *dalsi; }CLOVEK; CLOVEK *prvy, *aktualny, *novy; novy = (CLOVEK *) malloc(sizeof(CLOVEK)); novy->meno = “Jurko”; novy->rocnik = 3; novy->dalsi = NULL; aktualny->dalsi = q; //aktualny->dalsi->dalsi = q;

  43. Spájaný jednosmerný zoznam

  44. Spájaný jednosmerný zoznam CLOVEK *prvy, *aktualny, *zmaz; //zmazatprvokaktualny zmaz=prvy; //zapredpokladuzenemazemeprvyprvok while (zmaz->dalsi==aktualny) zmaz=zmaz->dalsi zmaz->dalsi=aktualny->dalsi aktualny->dalsi=NULL free(aktualny) aktualny=NULL aktualny=zmaz Podobneaj pre pridanie prvku pred aktualny

  45. Dynamické štruktúry – FIFO • FIFO = first in firstout = rad • Implementácia jednosmerného spájaného zoznamu • Pridávať je možné len na koniec zoznamu • Odoberať prvky sa dá len z konca zoznamu

  46. Dynamické štruktúry – LIFO • LIFO = last in firstout = zásobnik • Implementácia jednosmerného spájaného zoznamu • Pridávať je možné len na začiatok (koniec) zoznamu • Odoberať prvky sa dá len zo začiatku (konca) zoznamu

  47. Kruhový jednosmerný zoznam • Prvý prvok ukazuje na posledný

  48. Spájaný obojsmerný zoznam typedefstructpolozka { int hodnota; structpolozka *p_dalsi; structpolozka *p_pred; }POLOZKA; • Každý prvok ukazuje na nasledujúci prvok a predchádzajúci prvok • Posledný prvok ukazuje ďalej na NULL • Prvý prvok ukazuje na predchádzajúci ako na NULL • Treba si pamätať prvý/posledný prvok

  49. Spájaný obojsmerný zoznam

More Related