programare in limbajul c – cursul 11 p ointeri prof. univ. dr. constantin popescu

16
Programare in limbajul C – Cursul 11 Pointeri Prof. univ. dr. Constantin Popescu

Upload: alexia

Post on 26-Jan-2016

34 views

Category:

Documents


2 download

DESCRIPTION

Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu. Agenda. Declararea pointerilor Pointeri şi tablouri Aritmetica pointerilor Scăderea pointerilor C ompararea pointeri lor Pointeri null. Pointeri. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Programare in limbajul C – Cursul 11Pointeri

Prof. univ. dr. Constantin Popescu

Page 2: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Agenda Declararea pointerilor Pointeri şi tablouri Aritmetica pointerilor Scăderea pointerilor Compararea pointerilor Pointeri null

Page 3: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Pointeri Cind o variabila este definita,

compilatorul aloca o adresa reala de memorie pentru aceasta variabila:– int x; va aloca 4 bytes in

memoria principala, care va fi utilizata pentru a stoca o valoare intreaga.

Cind o valoare este asignata la o variabila, valoarea este plasata in memoria ce a fost alocata:– x=3; va stoca intregul 3 pe 4

bytes din memorie.

00000000

00000000

00000000

00000011

x

Page 4: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Pointeri Cind valoarea unei variabile este

utilizata, continutul din memorie este utilizat:– y=x; va citi continutul de 4 bytes

din memorie si apoi il va asigna la variabila y.

&x reprezinta adresa lui x. (operatorul de adresare &)

Adresa poate fi pasata la o functie:– scanf("%d", &x);

Adresa poate fi stocata intr-o variabila ……

00000000

00000000

00000000

00000011

x

y

Page 5: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Declararea pointerilor Declararea unei variabile pointer se face astfel:

tip *numepointer; De exemplu:

– int * p1; p1 este o variabila care pointeaza la un intreg, (sau p1 este un pointer intreg)

– char *p2; p2 este un pointer la un caracter– unsigned int * p3;

p1 = &x; /* Stocheaza adresa lui x in p1 */scanf("%d", p1); /* sau scanf("%d",&x); */

O declaraţie pointer simplă se face în felul următor: int *ip;

Declararea (şi iniţializarea) unei variabile i de tip int, şi setarea pointerului ip să pointeze la ea, se face astfel:

int i = 5;ip = &i;

Page 6: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Pointeri Expresia de atribuire ip = &i conţine ambele părţi ale

"procesului cu două etape": &i generează un pointer la i şi operatorul de atribuire atribuie noul pointer variabilei ip. Acum, ip "pointează la" i, ceea ce putem ilustra cu următoarea figură:

De exemplu putem scrie o secvenţă de genul: printf("%d\n", *ip);

care va tipări 5, întrucât ip pointează la i şi i are valoarea 5 (momentan).

Putem scrie o instrucţiune de forma:

*ip = 7; ceea ce semnifică "setează valoarea a ceea ce

pointează ip la 7". Rezultatul atribuirii *ip=7 este că valoarea lui i se va modifica la 7, iar figura se schimbă în felul următor:

Page 7: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Pointeri Dacă apelăm funcţia printf("%d\n", *ip)

aceasta va tipări 7. Când scriem *ip = 7, schimbăm valoarea

pointată de ip, dar dacă declarăm o altă variabilă j:

int j = 3;

ip = &j; am schimbat variabila pointer ip. Figura o

modificăm acum astfel: Dacă declarăm o altă variabilă pointer:

int *ip2; Atunci putem scrie:

ip2 = ip; Acum ip2 pointează aceeaşi zonă ca şi ip; am

făcut de fapt o "copie" a săgeţii:

Page 8: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Pointeri Urmatoarea atribuire face ca ip2 să pointeze aceeaşi zonă ca şi ip

(adică va pointa din nou la i). ip2 = ip;

Urmatoarea instrucţiune stochează la locaţia pointată de ip2, o copie a valorii pointate de ip.

*ip2 = *ip; E important să facem distincţie între un pointer şi valoarea pointată

de acel pointer. Variabila ip nu se poate seta la 5 cu o instrucţiune de genul:

ip = 5; /* GREŞIT */ Cifra 5 fiind o constantă de tip int, iar ip fiind un pointer. Probabil că vrem să setăm valoarea pointată de ip la 5, ceea ce se

realizează prin instrucţiunea:

*ip = 5;

Page 9: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Pointeri Exemplu:

void min_max(int a, int b,

int *min, int *max){

if(a>b){

*max=a;

*min=b;

}

else{

*max=b;

*min=a;

}

}

int main()

{

int x,y;

int small,big;

printf(“Doi intregi: ");

scanf("%d %d", &x, &y);

min_max(x,y,&small,&big);

printf("%d <= %d", small, big);

return 0;

}

Page 10: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Pointeri şi tablouri

Pointerii nu trebuie în mod obligatoriu să pointeze la variabile simple.

Aceştia pot pointa şi la elementele unui tablou. De exemplu, putem scrie:

int *ip;

int a[10];

ip = &a[3]; Ceea ce obţinem este că ip va pointa la al patrulea element al

tabloului a (tablourile sunt indexate începând de la zero). Putem ilustra situaţia în felul următor:

Page 11: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Aritmetica pointerilor Variabila ip am folosit-o la fel ca în secţiunea precedentă: *ip ne dă

valoarea pointată de ip, care în acest caz va fi val. lui a[3]. Ştim că pointerul ip indică elementul de pe poziţia 3 a tabloului şi atunci

putem să adunăm valoarea 1 lui ip:ip + 1

În C, obţinem un pointer la următorul element al tabloului, în acest caz acesta elementul este a[4].

Putem atribui noul pointer unei alte var. pointer:

ip2 = ip + 1; Dacă scriem:

*ip2 = 4; Am setat valoarea lui a[4] la 4. Dar nu e necesar să atribuim o nouă

valoare pointer unei variabile pointer pentru a o folosi; putem calcula o nouă valoare pointer şi să o folosim imediat:

*(ip + 1) = 5;*(ip + 3) = 7;*(ip - 2) = 4;

Page 12: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Scăderea pointerilor şi compararea lor Este valabilă expresia

ip2 - ip1 = 3 Când facem dif. dintre doi pointeri, atâta timp cât ei pointează în

acelaşi tablou, rez. va fi nr. de el. ce separă cei 2 pointeri. Doi pointeri se pot compara: doi pointeri sunt egali dacă

pointează aceeaşi variabilă sau acelaşi element al unui tablou. Când se testează egalit. sau inegalitatea a doi pointeri aceştia

nu trebuie în mod obligatoriu să pointeze în acelaşi tablou. Fragmentul de cod de mai jos copiază 10 elemente din tabloul

array1 în array2, folosind pointeri:

int array1[10], array2[10];int *ip1, *ip2 = &array2[0];int *ep = &array1[10];for(ip1 = &array1[0]; ip1 < ep; ip1++)

*ip2++ = *ip1; Pointerul ep pointează dincolo de ultimul el. ce se va copia.

Page 13: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Exemplu Funcţia mystrcmp compară

două şiruri de caractere caracter cu caracter:

#include <stdio.h>int mystrcmp(char str1[], char

str2[]);int main(){

char str1[100],str2[100];printf("Introduceti sirul 1:\n");gets(str1);printf("Introduceti sirul 2:\n");gets(str2);printf("Sirurile sunt: %d\n", mystrcmp(str1,str2));return 0;

}

int mystrcmp(char str1[], char str2[]){ char *p1=&str1[0],*p2=&str2[0]; while(1) { if(*p1 != *p2) return *p1 - *p2; if(*p1 == '\0' || *p2 == '\0') return 0; p1++; p2++; }}

Page 14: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Pointeri null (1) Un pointer null este o valoare specială pentru care este

garantat faptul că nu pointează nicăieri. Aceasta înseamnă că nici un alt pointer valid la o altă variabilă

sau la un element al unui tablou nu va fi egal cu pointerul null. Pentru a stabili valoarea unui pointer la null se foloseşte

constanta predefinită NULL, care este definită în mai multe fişiere header standard printre care: <stdio.h>, <stdlib.h>, <string.h>.

Pentru a iniţializa un pointer la pointerul null se poate folosi o secvenţa de cod:

#include <stdio.h>. . .int *ip = NULL;

Pentru a testa egalitatea unui pointer cu valoarea NULL, înainte de a folosi pointerul, putem folosi o secvenţă de genul:

if(ip != NULL)printf("%d\n", *ip);

Page 15: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Pointeri null (2)

La pointerul null ne putem referi folosind şi constanta zero Pentru a seta valoarea pointerilor la null, vom folosi o

instrucţiune de genul:int *ip = 0;

De fapt NULL este o macrodefiniţie care de obicei are valoarea, sau textul de substituţie, 0.

Se poate testa un pointer pentru a vedea dacă este diferit de null prin instrucţiunea:

if(ip) printf("%d\n", *ip);

Aceasta instrucţiune este echivalentă cu:if(ip != NULL) printf("%d\n", *ip);

Instructiunea if(ip) este echiv. cu if(ip != 0) şi cu if(ip != NULL).

Page 16: Programare in limbajul C – Cursul 11 P ointeri Prof. univ. dr. Constantin Popescu

Versiunea functiei strstr#include <stddef.h>char *mystrstr(char input[], char pat[]){

char *start, *p1, *p2;for(start = &input[0]; *start != '\0'; start++){

p1 = pat;p2 = start;while(*p1 != '\0') {

if(*p1 != *p2) break;p1++;p2++;

}if(*p1 == '\0') return start;

}return NULL;

}