Programozás C nyelven (9. ELŐADÁS) Sapientia EMTE 2015-16
1
POINTEREK – ismétlés px p1
int main(){ double x = 3.14, *px = &x; unsigned char *p, *p1, *p2; p1 = (unsigned char*)px; p2 = p1 + sizeof(double); for ( p = p2 - 1 ; p >= p1 ; --p ){ binarisan(*p); cout << ‘ ’; } return 0; }
… 00011111 10000101
11101011 01010001
3.14 10111000 00011110 00001001 01000000 p2
…
void binarisan (unsigned char c){ int n = sizeof(unsigned char) * 8; int i, b[n]; for ( i = 0 ; i < n ; ++i ) { b[i] = c%2; c /= 2; } for ( i = n-1 ; i >= 0 ; --i ) { cout << b[i]; } } 01000000 00001001 00011110 10111000 01010001 11101011 10000101 00011111
x
POINTER-ek alkalmazásai (címszerinti paraméterátadás)
75001 Paris, France
75001 Paris, France
POINTER-ek alkalmazásai (címszerinti paraméterátadás) Írj függvényt két változó tartalmának kicserélésére! void csere_1(int,int); int main(){ int a = 2, b = 3; csere_1(a,b); cout << a << ‘ ’ << b; 2 3_ return 0; } void csere_1(int x, int y){ int v; v = x; x = y; y = v; } a 2
b 3 main
x 2
y 3
v
csere_1
void csere_2(int*,int*); int main(){ int a = 2, b = 3; csere_2(&a,&b); cout << a << ‘ ’ << b; 3 2_ return 0; } void csere_2(int *pa, int *pb){ int v; v = *pa; *pa = *pb; *pb = v; } a 2 b 3 *pa *pb main
pa &a pb &b v csere_2
POINTER-ek alkalmazásai (1D-tömbök átadása függvénynek) Írj függvényeket számsorozat beolvasására/kiírására! void beolvas(int*,int*); void kiir(int*,int); int main(){ int n, a[100]; beolvas(a,&n); kiir(a,n); return 0; }
void beolvas(int *b, int *pn){ ifstream fin; fin.open(“szamsor.txt”); if (…) {...} szamsor.txt
5 2 3 51 0 -6
int i; fin >> *pn; for( i = 0 ; i < *pn ; ++i ){ fin >> b[i]; }
a n ?
? ? … ?
b a
pn &n
*pn main
beolvas
fin.close();
}
A tömbök implicite címszerint adódnak át!
POINTER-ek alkalmazásai (1D-tömbök átadása függvénynek) Írj függvényeket számsorozat beolvasására/kiírására! void beolvas(int*,int*); void kiir(int*,int); int main(){ int n, a[100]; beolvas(a,&n); kiir(a,n); return 0; } szamsor.txt 5 2 3 51 0 -6
void kiir(int *a, int int i; for( i = 0 ; i < n cout << a[i] << } 2 cout << ‘\n’; _ }
n){
; ++i ){ ‘ ’; 3 51 0 -6
a n 5
2 3 … ?
main
a a
n 5
kiir
POINTER-ek alkalmazásai (2D-tömbök átadása függvénynek) Írj függvényt 2D-tömbben tárolt mátrix kiírására! void kiir ( int(*)[100], int, int ); int main(){ int *x[100];// int-pointer TÖMB int n, m, b[50][100]; int (*x)[100];// POINTER int-tömbre . . . kiir(b,n,m); void kiir ( int(*b)[100], int n, int m ){ int i,j; return 0; for( i = 0 ; i < n ; ++i ){ } for( j = 0 ; j < m ; ++j ){ cout << b[i][j] << ‘ ’; b … } … cout << ‘\n’; ... } … }
Generálj n hosszú véletlen-számsorozatot (n<10000), melynek elemei a [0,10) intervallumba essenek. Készíts szám-előfordulási statisztikát! #include <stdlib.h> #include
int main(){ int n,i,a[10000],st[10]={0}; srand(time(NULL)); cin >> n; for( i = 0 ; i < n ; ++i ){ a[i] = rand() % 10; ++st[a[i]]; } for(i=0;i<10;++i){cout << i << return 0; }
? ? ? ? ? ? … ? 0 1 2 3 4 5
9999
0 0 0 0 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8 9
pazarlás 2 3 5 3 3 ? … ? 0 1 2 3 4 5
9999
0 0 1 3 0 1 0 0 0 0 0 1 2 3 4 5 6 7 8 9
5 0:0 1:0 2:1 3:3 4:0 5:1 6:0 7:0 8:0 9:0 _
‘:’ << st[i] <<‘\n’;}
Dinamikus helyfoglalás/változók
(malloc,calloc,realloc,free)
#include <stdlib.h> // tartalmazza malloc,… deklarációit #include st a int main(){ ? ? 5 0:0 int n, i, *a, *st; 1:0 ? ? ? ? ? 0 0 0 0 0 0 0 0 0 0 srand(time(NULL)); 2:1 0 1 2 3 4 0 1 2 3 4 5 6 7 8 9 cin >> n; 3:3 a = (int*)malloc(n*sizeof(int)); if(a==NULL){… return 0;} 4:0 st = (int*)calloc(10,sizeof(int)); if(st==NULL){…} 5:1 6:0 for( i = 0 ; i < n ; ++i ){ 2 3 5 3 3 7:0 a[i] = rand() % 10; 8:0 0 1 2 3 4 ++st[a[i]]; 9:0 } 0 0 1 3 0 1 0 0 0 0 _ 0 1 2 3 4 5 6 7 8 9
for(i=0;i<10;++i){cout << i << ‘:’ << st[i] <<‘\n’;} free(a); free(st); return 0; }
Dinamikus helyfoglalás/változók (malloc,calloc,realloc,free) • void* malloc (size_t size);
– Size of the memory block, in bytes • size_t is an unsigned integral type
– If the function failed to allocate the requested block of memory, a null pointer is returned
• void* calloc (size_t num, size_t size); – … and initializes all its bits to zero
• void* realloc (void* ptr, size_t size);
– Changes the size of the memory block pointed to by ptr – The function may move the memory block to a new location (whose address is returned by the function)
• void free (void* ptr); // ptr = NULL;
Dinamikus helyfoglalás/változók (malloc,calloc,realloc,free) • Minden malloc/calloc/realloc-ot kövessen NULL-tesztelő if. • Minden malloc/calloc/realloc-nak legyen meg a free párja. • Tanácsos a free utasítást követőe a poi ter nullázni. – Megtévesztő, ha egy poi ter e lefoglalt területre.
0,
égse
utat
• Biztonságosabb, ha a NULL makró helyet 0-t használunk. – C++ -ban a null kulcsszót.
2D dinamikus tömbök
b int** 0
1
0 int*
int
int
…
int
…
int
1 int*
int
int
…
int
…
int
… b[i] i int*
j
m
b[i][j] int
int
…
int
…
int
int
int
…
int
…
int
… n int*
int n, m, i, **b; cin >> n >> m; for( i=0 ; i
int double_cmp ( const void *, const void * ); int main(){ . . . int n, i; double *a; fin >> n; a = (double*)malloc(n*sizeof(double)); … for ( i = 0 ; i < n ; ++i ){ fin >> a[i]; } qsort ( a, n, sizef(double), double_cmp ); for ( i = 0 ; i < n ; ++i ){ fout << a[i] << ‘ ’; } int double_cmp ( const void *p1, const void *p2 ){ free(a); double *q1 = (double *)p1; return 0; double *q2 = (double *)p2; } if ( *q1 < *q2 ) { return -1; } else if ( *q1 > *q2 ) { return 1; } else { return 0; } }
Függvénypointerek (qsort)
Összefoglalás • Címszerinti-paraméterátadás • A tömbök implicite címszerint adódnak át • A 2D-tömbök nevei, mint pointerek, a 0. sor címét tárolják • Dinamikus helyfoglalás: malloc, calloc, realloc, free dinamikus 1D, 2D-tömbök • qsort void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))