A tétel (record) tétel: különböző típusú adatokat csoportosít, ezeket egyetlen adatként kezeli, de hozzáférhetünk az elemeihez is A tétel elemei mezők. Például tétel: személy elemei: név, lakcím, születési dátum kétféle tételtípus: rögzített tételtípus személy: név cím születési dátum változó tételtípus diák: név évfolyam ösztöndíj (igen) ösztöndíj összege diák: név évfolyam ösztöndíj ((nem) A mezőket az azonosítójukon keresztül érhetjük el: tételazonosító.mezőazonosító 1
Műveletek a tételek szintjén: értékadás mezőkiválasztás A tétel absztrakt adattípus Specifikáció: elemek: véges számú, nem rendezett, nem homogén adathalmaz, minden adat típusa egyénenként meghatározott szerkezet: azonosító minden elemnek (kölcsönös megfeleltetés) műveletek: értékadás egy mezőnek mező értékének lekérdezése értékadás tételek között Legyen R egy tétel típusú azonosító, id egy mező azonosítója (R-ben). Értékadás egy mezőnek: bemenet: R tétel id mezője, v azonosító v. konstans, eredmény: R előfeltétel: v típusa azonos id típusával utófeltétel: az R tétel id mezőjének új értéke v lesz C-ben: R.id = v, Pascalban: R.id := v 2
Mező értékének lekérdezése: bemenet: R tétel id mezője, eredmény: v előfeltétel: v típusa azonos id típusával utófeltétel: v értéke az R tétel id mezőjének értéke lesz C-ben: v = R.id, Pascalban: v := R.id Értékadás tételek között: bemenet: R 2 tétel, eredmény: R 1 tétel előfeltétel: R 1, R 2 azonos típusúak utófeltétel: R 1 felveszi R 2 értékét C-ben: R 1 = R 2, Pascalban: R 1 := R 2 Tételek C-ben és Pascalban C-ben Pascalban struct tétel{ típus_1 mezőlista_1; típus_2 mezőlista_2;... típus_n mezőlista_n; } változólista; type tétel=record mezőlista_1: típus_1; mezőlista_2: típus_2;... mezőlista_n: típus_n; end; struct tétel változólista; var változólista: tétel; 3
C++-ban egyéb lehetőségek: struct vektor{ int* e; int d; void init(int* e0, int d0); void torol() {delete [] e;} void negyzet(); void kiir(); }; void vektor::init(int* e0, int d0); { d=d0; e = new int [d]; for (int i=0; i<d; i++) e[i]=e0[i]; } void vektor::negyzet() { for (int i=0; i<d; i++) e[i] *=e[i]; } void vektor::kiir() { for (int i=0; i<d; i++) cout << e[i] << ; cout << endl; } 4
Az objektumelvű programozásban újabb lehetőségek: osztályok, objektumok átveszik a tétel szerepét Tömbök (array) tömb: azonos típusú elemek halmaz, a memóriában folytonosan helyezkednek el felhasználás: tömbazonosító, indexelés leggyakoribbak: egydimenziós tömb (vektor): [első..utolsó] A... első első+1 első+2 utolsó 1 utolsó hivatkozás: A[i] kétdimenziós tömb (mátrix) A... i A[i, j]...... j sorok, oszlopok hivatkozás: A[i, j] vagy A[i][j] 5
Ábrázolásmódok deklaráció (példák): Pascalban: var változó : array[elsőindex..utolsóindex] of típus; var változó : array[elsőindex1..utolsóindex1, elsőindex2..utolsóindex2] of típus; var v: array[1..20] of integer; var m: array[1..10,1..15] of real; v[12], m[2,6] C++-ban típus változó[méret]; nullával kezdődő index típus[méret] változó; típus változó[méret] = konstanslista; típus[méret] változó = konstanslista; int a[5] int a[5]={1,2,3,4,5} int a[]={1,2,3,4,5} 5 elemű tömb, hivatkozások: a[0],...a[4] double b[6][5] int c[3][2]={1,2,3,4,5,6} 30, illetve 6 elemű tömbök, hivatkozások pl.: b[0][4], c[2][1] 6
helyfoglalás Pascalban statikus C-ben: malloc, calloc, free függvények a stdlib.h-ból int sz[6]; statikus helyfoglalás float *fp fp = (float*)malloc(5*sizeof(float)), dinamikus helyfoglalás fp[2] hivatkozás a 2. elemre free(fp) C++-ban: new és delete operátorok int * c = new int[10]; delete [] c; 7
#include<stdio.h> #include<stdlib.h> // malloc miatt main(){ int a[10], c[]={0,1,2,3,4,5,6,7,8,9}, *p; for (int i=0; i<10;i++) a[i]=c[i]*c[i]; for (i=0; i<10;i++) printf("%5d", a[i]); printf("\n"); for (p=a; p-a<10;p++) printf("%5d", *p); printf("\n\n"); int b[5][5]; for (i=0; i<5;i++) for (int j=0; j<5;j++) b[i][j]=i+j; 8
for (i=0; i<5;i++) { for (j=0; j<5;j++) printf("%5d", b[i][j]); printf("\n"); }; printf("\n"); // egydimenzios tomb dinamikusan int n, *x; printf("n="); scanf("%d",&n); x=(int*)malloc(n*sizeof(int)); for (i=0; i<n;i++) { x[i]=i; printf("%4d", x[i]); } printf("\n"); free (x); 9
// ketdimenzios tomb dinamikusan int m; int **y; printf("m="); scanf("%d",&m); printf("n="); scanf("%d",&n); y=(int**)malloc(m*sizeof(int*)); for (i=0; i<m;i++) y[i]=(int*)malloc(n*sizeof(int)); for (i=0; i<m;i++) for (j=0; j<n;j++) y[i][j]=i*j; for (i=0; i<m;i++) {for (j=0; j<n;j++) printf("%5d", y[i][j]); printf("\n"); }; printf("\n"); } 10
Tömbök megfeleltetési függvényei (Array Mapping Functions) 10 soros 20 oszlopos mátrix esetében: típus A[10][20] a 0,0... a 0,19 a 1,0... a 1,19... a i,j... a 9,0... a 9,19 0 19 20 39 k 180 199 = 20i + j Legyen A n-dimenziós tömb: felső indexhatárok: s 1, s 2,... s n alsó indexhatár mindenhol 0 (azaztípus A[s 1 ][s 2 ]... [s n ]) Aktuális index: [i 1 ][i 2 ]... [i n ]. Mennyi k (az A i1,i 2,...,i n elem sorszáma)? k = n 1, ha j = n δ j i j, ahol δ j = n s k ha 1 j < n. j=1 k=j+1 Ha címet szeretnénk: cím(a i1,i 2,...,i n ) = A + sizeof(típus) n δ j i j j=1 11
A cím kiszámítása C++-ban, ha a típust T-vel jelöljük: unsigned int product = 1; T* address = A; for (int j = n; j >= 1; --j){ address += product * i j ; product *= s j ; } A tömbök paraméterei Az A tömb címe legyen a, elemei mérete h, a dimenzió n, alsó indexhatárai: e 1, e 2,... e n felső indexhatárai: u 1, u 2,...u n, aktuális indexek: i 1, i 2,... i n. egydimenziós tömb: indexhatárok: e, u cím(a i ) = cím(a e ) + h(i e) = (a he) + hi = c 0 + c 1 i, ahol c 1 = h, c 0 = a c 1 e kétdimenziós tömb: indexhatárok: e 1, e 2, u 1, u 2 cím(a ij ) = cím(a e1 e 2 ) + h(i e 1 )(u 2 e 2 + 1) + h(j e 2 ) = c 0 + c 1 i + c 2 j, ahol c 2 = h, c 1 = (u 2 e 2 + 1)c 2, c 0 = a c 1 e 1 c 2 e 2 12
n-dimenziós tömb: indexhatárok: e 1, e 2,... e n ; u 1, u 2,... u n cím(a i1,i 2,...,i n ) = c 0 + c 1 i 1 + c 2 i 2 +... + c n i n c n = h... c k 1 = (u k e k + 1)c k, ahol 1 < k n... c 0 = a c 1 e 1 c 2 e 2... c n e n Sajátos tömbök Háromszögű mátrix Legyen a következő mátrix: a 11 0 0... 0 a 21 a 22 0... 0 A = a 31 a 32 a 33... 0............... a n1 a n2 a n3... a nn Kezdőcím: a, elemméret h: cím(a ij ) = a + ( 1 + 2 + 3 +... + (i 1) ) h + (j 1)h hi(i 1) = a + + (j 1)h 2 = c 0 + c 1 i(i 1) + c 2 j 13
ahol c 2 = h, c 1 = c 2 2, c 0 = a h. Ritka tömbök A nem nulla elemeket őrizzük csak meg: (i, j, a ij ) Háromsoros ábrázolás 1 i m, 1 j n Eredeti mátrix: a 11 a 12 a 13 a 14 a 15 a 16 a 17 a 21 a 22 a 23 a 24 a 25 a 26 a 27 a 31 a 32 a 33 a 34 a 35 a 36 a 37 = Háromsoros ábrázolás: sor = (1,1,2,2,3,3) i oszlop = (3,6,2,6,6,7) j érték = (4,5,1,7,8,9) a ij 0 0 4 0 0 5 0 0 1 0 0 0 7 0 0 0 0 0 0 8 9 14
A ritka tömb leképezése Leképez 1. k := 0 2. for i := 1 to m m a sorok száma 3. do for j := 1 to n n az oszlopok száma 4. if a ij 0 5. then k := k + 1 6. sor k := i 7. oszlop k := j 8. ertek k := a ij 9. return k, sor, oszlop, ertek Adott indexű elem lekérdezése Adott a három vektor, és k értéke (mindegyik vektor ennyi elemű): Keres(i, j) 1. for p := 1 to k k a vektorok elemszáma 2. do if (sor p = i) és (oszlop p = j) 3. then return ertek p 4. if (sor p > i) 5. then return 0 6. return 0 15
Négysoros ábrázolás Mint előbb, csak még van egy negyedik vektor is, a mutató. Példa. a 11 a 12 a 13 a 14 a 15 a 16 a 17 a 21 a 22 a 23 a 24 a 25 a 26 a 27 a 31 a 32 a 33 a 34 a 35 a 36 a 37 = 0 0 4 0 0 5 0 0 1 0 0 0 7 0 0 0 0 0 0 8 9 sor = (1,1,2,2,3,3) i oszlop = (3,6,2,6,6,7) j érték = (4,5,1,7,8,9) a ij mutató = (0,4,0,5,0,0) A 4 a második elem a mutatóban, azt jelenti, hogy a háromsoros ábrázolásban a 2. index (1. sor, 6. oszlop: 5) egy olyan oszlopban (6.) levő elemet őriz, amely oszlopban még van nemnulla elem (a 7 a 2. sor 6. oszlopában), ennek az indexe szerepel itt, a 4 (negyedik helyen szerepel a háromsoros ábrázolásban). 16
Ritka mátrixok,,ábrázolása 17
#include <stdio.h> #include <stdlib.h> // dinamikusan helyet foglal egy matrixnak int ** lefoglal(int rows, int cols){ int i; int **m=(int**)malloc(rows*sizeof(int*)); for (i=0; i<rows;i++) m[i]=(int*)malloc(cols*sizeof(int)); return m; }; // kilistaz egy matrixot void listaz(int **m, int rows, int cols){ int i,j; for (i=0; i<rows;i++){ for (j=0; j<cols;j++) printf(" %4d ", m[i][j]); printf("\n"); } }; int main() {int i,j; int rows=10, cols=10; int **m, **x; m=lefoglal(rows,cols); x=lefoglal(rows,cols); // helyet foglal az m matrixnak // helyet foglal az x matrixnak for (i=0; i<10;i++) for (j=0; j<=10;j++)m[i][j]=i*j; // m erteket kap listaz(m,rows, cols); printf("\n"); x=m; listaz(x,rows, cols); // kilistazza az m matrixot // m-et x-be masolja // kilistazza az x matrixot return 0; }