Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
AccessAdobe photoshopAlgoritmiAutocadBaze de dateCC sharp
CalculatoareCorel drawDot netExcelFox proFrontpageHardware
HtmlInternetJavaLinuxMatlabMs dosPascal
PhpPower pointRetele calculatoareSqlTutorialsWebdesignWindows
WordXml


Expresii in care intervin pointeri

c



+ Font mai mare | - Font mai mic



Expresii in care intervin pointeri

In general, expresiile in care intervin pointeri respecta aceleasi reguli ca orice alte expresii din limbajul C.

Atribuirea pointerilor

Ca orice variabila, un pointer poate fi folosit in membrul drept al unei instructiuni de asignare (atribuire), pentru atribuirea valorii unui pointer unui alt pointer.

Exemplu:

# include <stdio.h>

void main (void)

/* Se afiseaza valoarea hexa a adresei lui x, nu valoarea lui x */

Se observa ca in functia printf() tiparirea se face cu formatul %p care specifica faptul ca variabilele din lista vor fi afisate ca adrese pointer.

Din cele de mai sus se observa ca operatia fundamentala care se executa asupra unui pointer este indirectarea, ceea ce presupune referirea la un obiect indicat de acel pointer.

Exemplu:

char c1 = 'a';

char *p = &c1; /* p contine adresa lui c1 */

char c2 = *p; /*c2 preia valoarea de la adresa p*/

printf ('c1 = %c c2 = %c', c1, c2);

Deci variabila indicata de p este c1, iar valoarea memorata in c1 este 'a', asa incat valoarea lui *p atribuita lui c2 este 'a'.

Operatii aritmetice efectuate asupra pointerilor

Utilizarea operatorilor de incrementare si decrementare

Fie secventa:

int *p1; /* pointer la intreg */

p1++;

De fiecare data cand se incrementeaza p1, acesta va indica spre urmatorul intreg. Astfel, daca p1 = 2000, dupa efectuarea instructiunii p1++, acesta va fi p1 = 2004 (va indica spre urmatorul intreg).

Dupa fiecare incrementare a unui pointer, acesta va indica spre urmatorul element al tipului sau de baza.

Dupa fiecare decrementare a unui pointer, acesta va indica spre elementul anterior.

Valoarea pointerilor va fi crescuta sau micsorata in concordanta cu lungimea tipului datelor spre care acestia indica, asa cum se poate vedea in exemplul urmator:

char *ch = 3000;

short int *i = 3000;

ch

3000

i

ch + 1

3001

ch + 2

3002

i + 1

ch + 3

3003

ch + 4

3004

i + 2

ch + 5

3005

ch + 6

3006

i + 3

Memoria

Cum valoarea indirectata de un pointer este o l-valoare, ea poate fi asignata si incrementata ca orice alta variabila. O l-valoare (left value) este un operand care poate fi plasat in stanga unei operatii de atribuire. Verificati utilizarea pointerilor din programul urmator:

# include <stdio.h>

void main(void)

In urma rularii sale, pe calculatoarele mai moderne obtinem rezultatul

i= 1,j= 2

pi= 0065FDE0,pj= 0065FDDC

*pi= 1 *pj= 1

*pi= 1 *pj= 0

++pj= 0065FDDE,++*pj= 1

Utilizarea operatorilor de adunare si de scadere

La sau dintr-un pointer, se pot aduna sau scadea valori de tip intreg. Rezultatul este un pointer de acelasi tip cu cel initial, indicand spre un alt element din tablou. De exemplu,

p1 = p1 + 9;

face ca p1 sa indice spre al 9-lea element avand tipul lui p1, considerand ca elementul curent este indicat de p1. Evident ca valoarea pointerului se va modifica corespunzator lungimii tipului datei indicata prin pointer.

Exemplu:

int *p1; /* Pointer la intreg */

p1 = p1 + 9;

Daca valoarea p1 = 3000, atunci p1 + 9 va avea valoarea:

(valoarea lui p1)+9*sizeof(int)=3000+9*4=3036

Aceleasi considerente sunt valabile in cazul in care un intreg este scazut dintr-un pointer. Daca doi pointeri de acelasi tip sunt scazuti, rezultatul este un numar intreg cu semn care reprezinta deplasamentul dintre cei doi pointeri (pointerii la obiecte vecine difera cu 1).

In cazul tablourilor, daca pointerul rezultat indica in afara tabloului, rezultatul este nedefinit.

Daca p indica spre ultimul membru dintr-un tablou, atunci (p+1) are valoare nedeterminata.

Observatii :

Nu se pot aduna sau scadea valori de tip float sau double la/sau dintr-un pointer.

Nu se pot efectua operatii de inmultire si impartire cu pointeri.

Exemplu: Scaderea a doi pointeri este exemplificata in programul:

# include <stdio.h>

void main(), *px;

j = &x[i]-&x[i-2];

px = &x[4]+i;

printf('%d %f %p %pn',j,*px,&x[4],px);

}

Compararea pointerilor

Doi pointeri de acelasi tip se pot compara printr-o expresie relationala, astfel: daca p si q sunt doi pointeri, atunci instructiunile:

if (p < q)

printf (" p indica spre o adresa mai mica decit q n ");

sunt corecte.

Compararea pointerilor se utilizeaza cand doi sau mai multi pointeri indica spre acelasi obiect comun.

Exemplu: Un exemplu interesant de utilizare a pointerilor consta in examinarea continutului locatiilor de memorie ale calculatorului.

/* Programul afiseaza continutul locatiilor de memorie de la o adresa specificata */

# include <stdio.h>

# include <stdlib.h>

dump (start);

void main (void)

dump (start)    /* Se defineste functia dump() */

unsigned long int start;

// Stop cand se apasa orice tasta }

Programul introduce cuvantul cheie far care permite pointerului p sa indice locatii de memorie care nu sunt in acelasi segment de memorie in care este plasat programul. Formatul %lu din scanf() inseamna: 'citeste un unsigned long int'. Formatul %X din printf() ordona calculatorului sa afiseze argumentul in hexazecimal cu litere mari (Formatul %x afiseaza in hexazecimal cu litere mici).

Programul foloseste explicit un sablon de tip pentru transferul valorii intregului fara semn, start, pe care il introducem de la tastatura, intr-un pointer. Functia kbhit() returneaza ADEVARAT daca se apasa o tasta, altfel returneaza FALS.

Utilizarea pointerilor ca parametri formali ai functiilor

In exemplele de pana acum, s-au folosit functii C care atunci cand erau apelate, parametrii acestor functii erau (intotdeauna) actualizati prin pasarea valorii fiecarui argument. Acest fapt ne indreptateste sa numim C-ul ca un limbaj de apel prin valoare. Exista totusi o exceptie de la aceasta regula atunci cand argumentul este un tablou. Aceasta exceptie este explicata, pe scurt, prin faptul ca valoarea unui nume al unui tablou (vector, matrice etc.) neindexate este adresa primului sau element.

Deci, in cazul unui argument de tip tablou, ceea ce se paseaza unei functii este o anumita adresa.

Folosind variabile pointer se pot pasa adrese pentru orice tip de date. Spre exemplu, functia scanf() accepta un parametru de tip pointer (adresa): scanf("%1f",&x);

Ceea ce este important de evidentiat este cum anume se poate scrie o functie care sa accepte ca parametri formali sau ca argumente pointeri ?.

Functia care receptioneaza o adresa ca argument va trebui sa declare acest parametru ca o variabila pointer. De exemplu, functia swap() care va interschimba valorile a doi intregi poate fi declarata astfel:

# include <stdio.h>

void swap(); /*Prototipul functiei swap()*/

void main(void)

void swap(int *pi, int *pj)



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 868
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved