BPC 1 E Potae a programovn 1 pro
BPC 1 E: Počítače a programování 1 pro obor EST PŘEDNÁŠKA 5 TÉMA a) Ukazatel b) Pole a ukazatel c) Pole ukazatelů d) Příklady Prezentace vznikla za podpory projektu: Komplexní inovace studijních programů a zvyšování kvality výuky na FEKT VUT v Brně OP VK CZ. 1. 07/2. 2. 00/28. 0193
Ukazatel (1/10) • Ukazatel (pointer) je datový typ sloužící k uložení adresy v paměti počítače • Požadovaná velikost pro uložení ukazatele v paměti (počet bytů) je dána paměťovým prostorem, který daný počítačový systém využívá • Pro malé mikrokontrolérové aplikace je ukazatel obvykle 16 ti bitový (2 B) s adresací paměťového prostoru do 64 k. B (adresa hexadecimálně 0 x 0000 až 0 x. FFFF)
Ukazatel (2/10) • Pokud je fyzický paměťový prostor větší, používá se segmentace – velký paměťový prostor je rozdělen na segmenty (stránky) o velikosti 64 k. B a ukazatel definuje adresu na dané stránce, tzv. blízký ukazatel, nebo je použit tzv. vzdálený ukazatel, který obsahuje i identifikaci příslušné paměťové stránky a adresu (offset) v rámci dané stránky
Ukazatel (3/10) • U 32 bitových systémů se používá 32 bitový ukazatel, tj. 4 B a adresy v hexadecimálním rozsahu 0 x 0000 do 0 x. FFFF, celkem 4 GB • U 64 bitových systémů se používá 64 bitový ukazatel, tj. 8 B, celkem 16 HB (hexabytů) • Pozn. 1 k. B = 210 B = 1024 B 1 MB = 220 B = 1024 k. B = 1048576 B 1 GB = 230 B = 1024 MB, 1 TB = 240 B = 1024 GB 1 PB = 250 B = 1024 TB, 1 HB = 260 B = 1024 HB, atd.
Ukazatel (4/10) • Ukazatelová aritmetika (Pointer aritmetics) zahrnuje výpočetní operace nad ukazateli. Adresovatelnou jednotkou může být 1 byte, 1 slovo (2 B), v jazyce C velikost datového typu (char = 1 B, int = 4 B, …), jenž ukazatel adresuje. int *a, *b; //pointers to integer int x; int y[5] = {1, 2, 3, 4, 5}; a = &x; //pointer a contents address of variable x *a = y[2]; //fill address defined by a by y[2], x=y[2] printf("%dn", x); b = &(y[3]); //pointer b contents address of var. y[3] *b = *a; //content of address pointed by a is copied to content of address pointed by b printf("%dn", y[3]); Příklad: BPC 1 E_Ex 42. c
Ukazatel (5/10) • Prvky jednorozměrného pole jsou v paměti řazeny za sebou, indexovat (ukázat na x-tý prvek) pole lze pomocí ukazatelů. int *adr; int arr[50], i; //pointer to integer adr = &(arr[49]); //pointer is set to the last element for(i=0; i<50; i++) { *adr = i; //a number is paste to the address //defined by pointer adr--; //pointer is shifted down (-1 element //of arr = -4 bytes due to int type } for(i=0; i<50; i++) printf("%dn", arr[i]); Příklad: BPC 1 E_Ex 43. c
Ukazatel (6/10) • Jméno pole bez indexu je ukazatelem na první prvek pole: zápis A[0] je ekvivalentní *A zápis A[5] je ekvivalentní *(A+5) int *adr; //pointer to integer int arr[50], i; adr = arr; //pointer is set to the first element for(i=0; i<50; i++) { *adr = i; //a number is paste to the address //defined by pointer adr++; //pointer is shifted up (+1 element //of arr = +4 bytes due to int type } for(i=0; i<50; i++) printf("%dn", arr[i]); Příklad: BPC 1 E_Ex 44. c
Ukazatel (7/10) • Př. Aplikace relačních operátorů na ukazatele int *a, *b, *c; int arr[20], i; a = arr; for(i=0; i<20; i++) b = arr+5; c = arr+15; a = arr; for(i=0; i<20; i++) { if (b<a && c>a) *a=0; a++; } for(i=0; i<20; i++) // pointers to integer {*a = i; a++; } printf("%3 d", arr[i]); //address a must be between b and c printf("%3 d", arr[i]); Příklad: BPC 1 E_Ex 45. c
Ukazatel (8/10) • Př. Integer v paměti po bytech int *a; //pointer to int char *b; //pointer to char int arr[5], i; for(i=0; i<5; i++) arr[i] = i; a=arr; for(i=0; i<5; i++) //int address and value displaying { printf("%x %3 dn", a, *a); a++; } b=arr; for(i=0; i<20; i++) //char (byte) addr. and value disp. { printf("%x %3 dn", b, *b); b++; } Příklad: BPC 1 E_Ex 46. c
Ukazatel (9/10) • Př. Float v paměti po bytech unsigned char *a; float num = 1. 2; int i; //pointer to uchar //float value in memory a=# for(i=0; i<4; i++) //four bytes of float value in mem. { printf("%x ", a); //address printf("%xn", *a); //content a++; } • Pro hodnotu 1, 2 uloženou jako typ float je v paměti uloženo (hexa) 9 A 99 99 3 F, uspořádání je od nejméně významného bytu pro nejvíce významný Příklad: BPC 1 E_Ex 47. c
Ukazatel (10/10) • 1, 2 ve float rozlišení má tedy tvar hexa: 0 x 3 F 9 9 9 A binárně: 0 b 0 -01111111 -001100110011010 • znaménko: 0 = + • exponent: 0 b 01111111 = 127 • mantisa: 0 b 001100110011010 = 1677722
Pole a ukazatel (1/3) • Dvourozměrné pole v paměti int *a; //pointer to int arr[4][5], i, j; for(i=0; i<4; i++) { for(j=0; j<5; j++) { arr[i][j]= 10*i+j; v printf("%3 d", arr[i][j]); } printf("n"); } a=arr; for(i=0; i<20; i++, a++) //20 elements of array in mem printf("%x %3 dn", a, *a); //printing Příklad: BPC 1 E_Ex 48. c
Pole a ukazatel (2/3) • Vícerozměrné pole v paměti int *a; //pointer to int arr[3][3][3], i, j, k; for(i=0; i<3; i++) for(j=0; j<3; j++) for(k=0; k<3; k++) arr[i][j][k] = 100*i + 10*j + k; for(i=0; i<27; i++, a++) //27 elements of array 3 x 3 x 3 printf("%x %3 dn", a, *a); //in memory printing Příklad: BPC 1 E_Ex 49. c
Pole a ukazatel (3/3) • Vícerozměrné pole a ukládání jeho prvků v paměti: • Ekvivalentní zápis: arr[i][j][k] = *(arr+i*3*3+j*3+k)
Pole ukazatelů (1/2) • Př. Aplikace pole ukazatelů – vyhledání pozic znaků v textu char text[] = "okolo kola okolkovala koala"; char *o[10], *c; //o is array of pointers int i=0, j; printf("Original string: %snn", text); printf("Addr. of the beginning of text: %xnn", text); o[i] = strchr(text, 'o'); while(o[i]) { c = o[i]+1; i++; o[i] = strchr(c, 'o'); //save addres of ’o’ to //array of pointers }
Pole ukazatelů (2/2) printf("Addresses of the character o: n"); for(j=0; j<i; j++) printf("%x - position %dn", o[j]-text); for(j=0; o[j]!=0; j++) // changing of all ’o’ by ’k’ *o[j]='k'; printf("nn. Changed string: %sn", text); Příklad: BPC 1 E_Ex 50. c
Příklady (1/7) • Př. Záměna znaků pomocí ukazatele char text[]="okolo kola okolkovala koala"; char *a; printf("Original string: %snn", text); a=text; while(*a!=NULL) { if(*a=='o') *a='k'; else if(*a=='k') *a='o'; a++; } printf("Changed string: %sn", text); Příklad: BPC 1 E_Ex 51. c
Příklady (2/7) • Př. Vyhledání a náhrada textu bez std. funkcí pomocí ukazatelů char text[]="sokol kolem jezdil kolem dokola"; char test[]="kol"; char ntext[]="-----"; char *a, *b, *c; int tst; a=text; b=test; printf("Original string: %snn", text); for(a=text; *a!=NULL; a++) { tst=1; c=a; for(b=test; *b!=NULL; b++, c++) if (*c!=*b) tst=0;
Příklady (3/7) if(tst) { c=ntext; for(b=test; *b!=NULL; b++, c++, a++) { *a=*c; } } } printf("Changed string: Příklad: BPC 1 E_Ex 52. c %sn", text);
Příklady (4/7) • Př. V řetězcové proměnné wtxt a btxt ve jsou uloženy zhuštěně pozice figurek bílého, resp. černého, na šachovnici se 64 políčky (8 x 8) ve formě písmeno řádku (A až H) a číslo sloupce (1 až 8). Doplňte program, který postupně projde texty ve wtxt a btxt a do pole field vloží na příslušná místa znaky 'W' a 'B' označující figurku příslušného hráče a situaci vytiskněte do konzolového okna. Procházení řetězci i polem řešte pomocí ukazatelů. #include <stdio. h> int main() { char wtxt[]="A 6 B 8 A 4 D 7 E 2 C 3 F 1 F 2"; char btxt[]="C 3 A 7 B 1 D 1 E 4 E 5 F 5 H 3 H 5"; char field[64]; char *p, *t, i, j;
Příklady (5/7) p=field; for(i=0, p=field; i<64; i++, p++) *p= ' '; p=wtxt; do { t=field+8*(*p-'A'); p++; t+=(*p-'1'); *t='W'; p++; } while(*p!='