P. 1
PointeriM1-B

PointeriM1-B

|Views: 84|Likes:
Published by Tudor Alexe

More info:

Published by: Tudor Alexe on Feb 20, 2012
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

04/02/2013

pdf

text

original

Pointeri

Cuprins
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Noţiuni introductive Operatori specifici pentru pointeri Operaţii cu pointeri Apelul prin adresă utilizând pointeri Pointeri şi referinţe Indirectarea multiplă Pointeri constanţi şi pointeri către constante Tablouri şi pointeri Funcţii pentru lucrul cu şiruri de caractere Pointeri spre funcţii Transferarea de argumente către funcţia main( ) Alocarea dinamică a memoriei Funcţii pentru manipularea zonelor de memorie
2

1. Noţiuni introductive
• Tipul pointer (indicator) reprezintă adresa unei locaţii de memorie
– adresele sunt valori numerice întregi fără semn

• Tipuri de pointeri:
– pointeri de date:
• conţin adresa unor variabile sau constante din memorie

– pointeri de funcţii:
• conţin adresa codului executabil din funcţii

– pointeri de obiecte:
• conţin adresa unui obiect

– pointeri generici sau pointeri void:
• conţin adresa unui obiect oarecare
3

Noţiuni introductive

• Pointerii de date se declară astfel:
tip *nume_pointer;

• Pointerii generici se declară astfel:
void *nume_pointer;

• Exemplu:
int *nptr; float *a, rezultat; int *tabptr[10]; void *pgen;

4

2. – expresia *nume_pointer poate fi folosită atât pentru a obţine valoarea obiectului cât şi pentru a o modifica: var = *nume_pointer *nume_pointer = expr 5 ..... la adresa nume_pointer . Operatori specifici pentru pointeri • Operatorul & (adresare sau referenţiere): – permite aflarea adresei unei variabile oarecare: – rezultatul este un pointer la tipul variabilei &nume_var • Operatorul * (indirectare sau dereferenţiere): – se foloseşte pentru a afla ce se găseşte la o adresă: *nume_pointer <-> .

deci cu adresa unei date) înainte de a fi utilizată: int *p. *p = 10.Operatori specifici pentru pointeri • Orice variabilă pointer trebuie definita cu o valoare validă (0 sau NULL. pentru ca lui p nu i s-a asignat o valoare Exemplu: void main(void) { int i=10. ptri = &i.. } 6 . i. *ptri).. *ptri). . i. *ptri = 20. nu e valida. printf("Valoare var : %d \nLa adresa var : %d" . printf("Valoare var : %d \nLa adresa var : %d" . // eroare. *ptri.

*p=2.k. • getch(). continut cout << "\nl= "<< l << " j= " << j << " Pointer adresa lui l (e p) = " << p << " Adresa lui j =" << &j << endl.h> • • • • • void main(){ int l=1. • k=*(p=&j)++.//modific pointerul p de la adresa lui j • cout << "\nk (j)= "<< k << " Valoarea lui j = " << j << " Adresa lui j =" << &j << " Adresa lui p (oper. *p. } 7 . oper. pointer =" << p<<endl. p=&l. #include <conio.• • • • //operatii pointeri asupra continut si asupra pointerului #include <iostream> using namespace std.//modific l. j=5.

5.q). double *dp. tipul pointerului determinand modul in care va fi tratat obiectul pointat: • Un pointer de un anumit tip nu va fi folosit să pointeze o dată de alt tip: int q. temp. *dp = 20. q=*p.Operatori specifici pentru pointeri • In C/C++ se permite ca ori ce tip de pointer sa pointeze ori unde in memorie.//voi scrie 8 locatii sau int *p.5. double q.//iau doar cat e specific unui int printf (“%f”. 8 . temp=20. p=&temp. dp = &q.

p=&y.Operatori specifici pentru pointeri • Pointerii generici (void *) nu sunt asociaţi unui anume tip de date: – dimensiunea zonei de memorie adresate şi interpretarea datelor din acea zonă nu sunt definite • Aceşti pointeri pot fi utilizaţi cu mai multe tipuri de date însă numai cu operatorul de conversie explicită (cast): int x. float y. // lui p i se atirbuie adresa de memorie unde pot fi flotanti *(float *)p = 20. . void *p.5.. p=&x.. // lui p i se atribuie adresa de memorie unde pot fi intregi *(int*)p = 10. 9 .

float *pf.. *((char*)pf) -> primul octet al unei variabile de tip float *((char*)pf+1) -> al doilea octet al unei variabile de tip float – Construcţia (char*) este folosită pentru accesul pe octet la zone de memorie de mărimi diferite 10 . ..Operatori specifici pentru pointeri • Operatorul cast poate modifica semnificaţia pointerilor: int *pi.

3. Operaţii cu pointeri • Cu ajutorul pointerilor se pot efectua operaţii de: – – – – – – atribuire comparare adunare scădere incrementare decrementare • In operaţii se ţine cont de faptul că adresele care reprezintă pointerii au valori numerice întregi fără semn 11 .

– Avem următoarele cazuri: • • • • tip1 este void. atribuirea este corectă tip1 si tip2 diferă. atunci compilatorul generează un avertisment sau o eroare 12 . atunci tip1 poate fi oarecare tip1 si tip2 sunt identice.Operaţii cu pointeri Atribuirea – Dacă: tip1 *id_ptr1. tip2 *id_ptr2. id_ptr1 = id_ptr2. atunci tip2 poate fi oarecare tip2 este void.

p1. .Operaţii cu pointeri Compararea a doi pointeri – Se face cu operatorii relaţionali dar numai în cazul în care pointerii pointează pe obiecte de acelaşi tip – Exemplu: int *p1. j.. *p2. p1=&i. p2). p2=&j. if (p1 < p2) printf ("p1= %n p2 = %n\n". 13 .. i.

Operaţii cu pointeri – Operatorii == şi != pot fi folosiţi pentru a compara pointeri cu o constantă specială NULL definită de obicei în stdio.h prin: #define NULL 0 – Pentru un pointer generic (void *p) atunci se pot face comparaţiile: p == NULL şi p != NULL – In C++ este recomandabil a folosi: if (p == 0) if (p != 0) <=> <=> if (!p) if (p) 14 .

float.) – Fie declaraţia: tip *id_ptr. char. id_ptr . scădere şi incrementare.Operaţii cu pointeri Adunare. etc. decrementare – Pot fi adăugate sau scăzute doar cantităţi întregi – Operaţiile se efectuează relativ la tipul pointerului (int.n • corespund adăugării/scăderii la adresa obţinută în cadrul variabilei id_ptr a valorii: n * sizeof(tip) – Analog se efectuează şi operaţiile de incrementare/decrementare doar că n este= 1/-1 – Rezultatul este corect doar atunci cand pointerul adreseaza un tablou si prin opearatia aritmetica se produce o deplasare in interiorul limitelor tabloului 15 . – Operaţiile: id_ptr + n.

1*8 16 . // dp va contine : adresa lui dp ..2*8 fp1++.Operaţii cu pointeri • Exemplu: float *fp1. double *dp. *fp2.//tf dp = &td[9]. fp1 = &tf[0]. td[10[. tf[10]. // dp va contine : adresa lui dp . // fp2 va contine : adresa lui tf + 5*4 dp = dp-2.. // fp1 va contine : adresa lui fp1 + 1*4 dp--.// // sizeof (float) = 4 // sizeof (double) = 8 fp2 = fp1+5. .

q=17. // se obţine întâi conţinutul de la adresa p // care apoi se incrementează cu 1 17 . v=*p++. p=&q. v. // întâi se aplica * şi apoi ++ asupra pointerului • Dacă se foloseşte varianta: v = (*p)++.Operaţii cu pointeri • Operaţia de incrementare/decrementare se poate aplica: – asupra pointerului însuşi – asupra obiectului pe care îl pointează • Dacă se foloseşte varianta: int *p.

adresa p1)/4 – Datorită rolului tipului la adunare şi scădere. . float *p1=&ft[4]. // i = (adresa p2.Operaţii cu pointeri Scăderea a doi pointeri – Este permisă numai pentru pointeri de acelaşi tip ce refera un tablou.. rezultatul fiind o valoare care reprezintă diferenţa de adrese divizată la dimensiunea tipului de bază – Adunarea pointerilor nu este permisă ! – Exemplu: float l.. operanzii nu pot fi pointeri void sau pointeri spre funcţii 18 .ft[9]. *p2=&ft[2]. l = p2-p1.

adresa variabilei: – ca şi parametri formali se pot folosi pointeri unde se vor copia aceste adrese 19 . orice operaţie efectuată în funcţie asupra parametrului formal nu afectează variabila – spunem că se lucrează cu copii ale parametrilor efectivi • Dacă vrem ca o funcţie să modifice o variabilă parametru efectiv.4. la apel. Apelul prin adresă utilizând pointeri • Transferul parametrilor prin valoare (implicit): – constă în încărcarea valorii parametrilor efectivi în zona de memorie a parametrilor formali – dacă parametrul efectiv este o variabilă. atunci trebuie să transmitem funcţiei.

} Apelul: schimba_2(&x. void schimba_2(int *a. int *b) { int temp. a=b. b=temp. y). temp=*a. int b) { int temp. } Apel: schimba_1(x. *a=*b.Apelul prin adresă utilizând pointeri void schimba_1(int a. &y). 20 . temp=a. *b=temp.

int x ). 21 . int x ). funcţia va primi doar adresa acelui tablou. argumentul folosit ca şi parametru efectiv fiind adresa tabloului asupra căruia se fac operaţii în funcţie int cauta(int *p. adică adresa primului element din tablou Variante: – parametrul formal este declarat ca un tablou fără dimensiune int cauta(int p[ ]. int n. • – parametrul formal este declarat ca un pointer către tipul tabloului.Apelul prin adresă utilizând pointeri • Dacă la apelul unei funcţii se foloseşte ca şi argument un tablou. int n.

int n.Apelul prin adresă utilizând pointeri // cautare pe un tablou int cauta(int *p. … int cauta(int *p. i++) { if(x == p[i]) return i. int x) { int i. val). int x ). 22 . i<n. MAX. } Apel: cauta(tab. int n. for(i=0. } return –1.

ca şi pointerii. int &r = i. conţin adrese de memorie • Se declară cu ajutorul operatorului de adresare ("&“) şi se iniţializează obligatoriu la inceput cu o adresă (a unei variabile sau a unei constante).//alias 23 . Pointeri şi referinţe • Referinţele. fiind un alias al ei: int i.5.

Pointeri şi referinţe • Accesul la o variabilă prin intermediul unei referinţe se face simplu fără a mai folosi operatorul de indirectare ca în cazul pointerilor: int i. … r = 1000. int *p.. p = &i. . // i = 1000 24 . *p = 100.. // i = 100 int i. int &r = i.

Pointeri şi referinţe • Diferenţe între pointeri şi referinţe: – după modul de definire: • * pentru pointeri • & pentru referinţe – după modul de utilizare: • pointerii: – se asociază unei variabile cu operatorul & şi se apelează cu operatorul * – pot fi asociaţi mai multor variabile la momente diferite de timp şi deci pot conţine adrese diferite • referinţele: – se asociază unei variabile şi numai uneia la definire – conţin tot timpul adresa aceleiaşi variabile fiind de fapt o redenumire (alias) a variabilei – li se asociază valori pe baza unei atribuiri simple 25 .

caz în care indirectarea este ascunsă şi nu este necesară dereferenţierea în funcţie (utilizarea operatorului *) 26 . tablouri de referinţe dar putem avea referinţe la pointeri – o referinţă nu poate avea valoarea NULL – o referinţă nu poate fi asociată unei alte variabile • Utilizare: – se folosesc rar variabile referinţe simple – uzual se folosesc la transmiterea parametrilor prin referinţă. referinţe la câmpuri de biţi. pointeri la referinţe.Pointeri şi referinţe • Restricţii: – nu sunt permise referinţe la referinţe.

*b = temp. *a = *b. } • // varianta cu referinţe void schimba(int &a. a = b. } • apelul : schimba(&i. b = temp.j). int *b) { int temp.Pointeri şi referinţe • // varianta cu pointeri void schimba(int *a. int &b) { int temp. • apelul : schimba(i. temp = *a. &j). 27 . temp = a.

Pointeri şi referinţe • Rezultatul unei funcţii se poate transfera prin referinţă astfel: int & func(.... } • Trebuie evitată returnarea adresei (prin pointer sau referinţă) unui obiect automatic. .) { static int var.. obiect care se distruge la ieşirea din funcţie 28 . return(var).

. pm = &p. p = &ch.... ch. .6. • Declararea se face utilizând un asterisc suplimentar în faţa numelui pointerului: char **pm. pointer care pointează locaţia care va conţine obiectul. Indirectarea multiplă • Când un pointer pointează alt pointer avem un proces de indirectare multiplă: Pointer către pointer -----> Pointer -----> Obiect • Primul pointer conţine adresa celui de-al doilea pointer. **pm = 'A'.. // lui ch i s-a asignat valoarea A prin 2 pointeri 29 . *p.

str1 = "ptr la const". // incorect // ok – pointeri constanţi char *const str2 = "pointer constant ". //str2 = "ptr const". // incorect // ok 30 . str2[0] = 'P'. Pointeri constanţi şi pointeri către constante • Există pointeri către constante şi pointeri constanţi (care nu pot fi modificaţi): – pointeri către constante const char *str1 = "pointer catre constanta". //str1[0] = 'P'.7.

Pointeri constanţi şi pointeri către constante – pointeri constanţi către constante const char *const str3 = "pointer constant la constanta". // incorect //str3[0] = 'C'. 31 . // incorect – un pointer poate. //str3 = "ptr const la const". indirect. modifica totuşi o variabilă declarată cu modificatorul const astfel: *(tip *)&var.

dest++.Pointeri constanţi şi pointeri către constante • O funcţie care are ca parametri formali pointeri dar nu are voie să modifice datele pointate de parametru efectiv arată astfel: void cifru(const char *src. src++. } } 32 . char *dest) { while(*src) { *dest = *src + 5.

const char *src). • Astfel de funcţii se mai folosesc şi pentru alocarea dinamică a memoriei. 33 . arborilor... prelucrarea listelor.Alte consideraţii referitoare la pointeri • In limbajul C/C++ se folosesc des funcţii care returnează pointeri • Exemplu: char *strcpy(char *dest.

34 .h> void main(void) { int n. &n). printf("\nReprezentarea in memorie a lui %d este: 0x%02x%02x%02x%02x\n". scanf("%d".Exemplul 1: #include <stdio. float r. *pr. *((unsigned char *)pn+1). *pn. *((unsigned char *)pn)). printf("\nIntroduceti un numar intreg: "). n. *((unsigned char *)pn+3). pn = &n. *((unsigned char *)pn+2).

r. pr = &r.printf("\nIntroduceti un numar real: "). *((unsigned char *)pr)). &r). *((unsigned char *)pr+2). *((unsigned char *)pr+1). scanf("%f". } 35 . printf("\nReprezentarea in memorie a lui %f este: 0x%02x%02x%02x%02x\n". *((unsigned char *)pr+3).

void main(void) { int x. &y).h> void schimba1(int a. int &rx=x. scanf("%d". int &b). &ry=y. 36 . int *b). printf("\nIntroduceti valoarea lui x: "). *py. int *px. &x). y.Exemplul 2: #include <stdio. int b). scanf("%d". void schimba3(int &a. printf("\nIntroduceti valoarea lui y: "). void schimba2(int *a.

schimba1(x. schimba2(&x. x. schimba3(x. x. y). } 37 . printf("\nNoile valori sunt: x = %d. y = %d\n". printf("\nNoile valori sunt: x = %d. y). x. &y). y = %d". y). y). y = %d". printf("\nNoile valori sunt: x = %d. y).

*b = temp. } void schimba2(int *a. a=b.void schimba1(int a. temp = *a. b=temp. } 38 . *a = *b. b = temp. int &b) { int temp. int b) { int temp. int *b) { int temp. } void schimba3(int &a. temp = a. temp=a. a = b.

p = &tab[0]. printf("\nElementele tabloului sunt: "). i++) { printf("\t%d".h> void main(void) { int tab[ ] = {1. 7. printf("\nElementele tabloului sunt: "). 3. 5. p++. } p = &tab[n-1]. for(int i=0. for(int i=0. 9}. int *p. i<n.Exemplul 3: #include <stdio. *p--). n = sizeof(tab)/sizeof(int). 39 . int n. i<n. *p). i++) printf("\t%d".

i++) printf("\t%d". p = &tab[n-1]. i<n. 40 . printf("\nElementele tabloului sunt: "). *(p-i)). i<n. i++) printf("\t%d".p = &tab[0]. for(int i=0. *(p+i)). printf("\nElementele tabloului sunt: "). for(int i=0.

i). i++) { if(p1 == p2) printf("\n\tPentru i=%d. for(int i=0. p1++. i<n. *p2. } } 41 . pointerii indica acelasi element\n". p2--. printf("\n\nCompararea pointerilor: "). p2 = p. p2-p1). printf("\n\nDistanta intre ultimul si primul element: %d\n".int *p1. p1 = &tab[0].

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->