Documente Academic
Documente Profesional
Documente Cultură
Memoria internă
Segmen:offset
Exemplu
1. *&nume reprezintă valoarea de la adresa variabilei nume (valoarea
variabilei nume).
Exemple
2. int* n; n este o variabilă de tip pointer spre întreg;
3. struct complex {a,b:real;}* x; x este o variabilă de tip pointer spre
o structură de tipul complex;
4. void* p; p este o variabilă de tip pointer spre void; p poate primi ca
valoare adresa unei zone de memorie de orice tip.
Dacă TIP este un tip oarecare (mai puţin void) atunci tipul TIP* este
adresa unei zone de memorie de un tip cunoscut. Operaţiile care se pot
efectua asupra zonei respective de memorie sunt definite de tipul acesteia.
Dacă TIP este void, atunci TIP* este adresa unei zone de memorie de tip
necunoscut. Deoarece nu se cunoaşte tipul zonei de memorie, nu sunt
definite operaţiile care se pot efectua asupra ei.
Tipuri dinamice de date 169
Exemple
5. int* nume; int a; float b;
nume = &a; este o atribuire corectă; nume are ca valoare adresa
variabilei a.
nume = &b; este o atribuire incorectă; nume poate primi ca
valoare doar adresa unei variabile întregi.
6. void* nume; pointer fără tip
int a; float b; variabile de tip întreg, respectiv real
nume = &a; atribuire corectă
nume = &b; atribuire corectă; nume poate primi ca
valoare adresa oricărei variabile, de orice tip.
Exemplu
7. int a,b,c; int* nume;
void* nume2;
b=5;
nume=&a;
170 Bazele programării calculatoarelor
*nume=b;
c=*nume+b;
nume2=&b;
*(int*)nume2=10;
c=*(int*)nume2;
nume nume2 c a b
4B 4B 2B 2B 2B
Tipuri dinamice de date 171
nume nume2 c a b
4B 4B 2B 2B 2B
Analog se execută operaţiile ++nume şi --nume.
Exemplu
8. float v[20];
float* p;
int i;
p=&v[i]; unde i poate avea valori între 0 şi 19
În urma atribuirii ++p sau p++, p va avea ca valoare adresa lui v[i] plus 4
octeţi, adică adresa lui v[i+1].
Exemplu
9. Fie p şi q pointeri spre tipul float (float* p, *q). Presupunînd că p a fost
iniţializat cu valoarea 0x0fff:0x3450, în urma operaţiei q=p+3, q primeşte
valoarea 0xfff:0x345c (se adună 3*4 octeţi). În urma operaţiei q=p-2, q
primeşte valoarea 0xffff:0x344a (se scad 2*4 octeţi).
precizaţi anterior) este adevărat (nenul) sau fals (zero) după cum nume este
egal, mai mare sau mai mic decît nume2. Doi pointeri sunt egali dacă
adresele care constituie valorile lor sunt egale. Privind memoria internă
liniar, începînd de la adresa 0 (zero), un pointer p este mai mare decît altul
q, dacă adresa pe care o conţine p este mai îndepărtată de începutul
memoriei decît adresa conţinută de q.
Este permisă şi compararea unui pointer cu o valoare constantă.
Uzual se foloseşte comparaţia cu valoarea NULL pentru a verifica dacă
pointerul a fost iniţializat (un pointer neiniţializat are valoarea NULL),
folosind unul din operatorii == sau !=. Valoarea NULL este definită în
stdio.h astfel: #define NULL 0
De multe ori se preferă comparaţia directă cu zero (nume==0 sau
nume!=0). În loc de nume==0 se poate folosi expresia nume. Aceasta se
interpretează astfel: dacă nume nu a fost iniţializat, atunci are valoarea
NULL (adică 0), deci expresia este falsă. În caz contrar valoarea expresiei
este nenulă, deci adevărată. Asemănător se foloseşte expresia !nume.
Exemplu
10. float* p,q,r,t;
float a,b;
p=&a; q=&b; r=&a;
a=5; b=7;
if(t) printf("Pointer initializat!\n");
else printf("Pointer neinitializat!\n");
if(p==r) printf("Pointeri egali\n");
else printf("Pointeri diferiti\n");
if(p>q) printf("%d\n",a);
else printf("%d\n",b);
Pe ecran se va afişa:
Pointer neinitializat!
Pointeri egali
7
deoarece t are valoarea NULL, variabilele p şi r au ca valoare adresa lui a,
iar q conţine adresa lui b, care este mai mare decît a lui a (datorită faptului
că a a fost alocat primul).
int m[50],* a, * b;
a=&m[i]; b=&m[j];
unde i şi j sunt întregi în intervalul [0..49]. Expresia a-b are valoarea i-j,
interpretată ca distanţă între adresele a şi b, exprimată în zone de memorie
de lungime sizeof(int).
Valoarea unei expresii diferenţă se calculează astfel: se face
diferenţa între cele două adrese (în octeţi), apoi se împarte la dimensiunea
tipului de dată referită de cei doi pointeri (tipul int în exemplul de mai sus –
vezi figura 10.2). Cei doi pointeri trebuie să refere acelaşi tip de dată, altfel
rezultatul nu are semnificaţie (trebuie să aibă tipuri identice). Operaţia este
utilă în lucrul cu masive.
m i j
a b
Exemplu
11. Un masiv cu trei dimensiuni float m[10][10][10] poate fi interpretat ca
un pointer spre un vector de pointeri spre matrice;
Un masiv cu n dimensiuni este tratat ca un pointer spre un vector de pointeri
Tipuri dinamice de date 175
Exemplu
12. float* v[10]; float* p; p=v;
După atribuire, pointerul p conţine adresa de început a masivului şi poate fi
folosit pentru referirea elementelor masivului. De exemplu, v[3] şi p[3]
referă aceeaşi zonă de memorie.
funcţiei main:
void main(int argc, char* argv[])
Exemplu
16. Dacă programul nu are nici un parametru, argc are valoarea 1, dacă
programul are doi parametri, argc are valoarea 3 etc.
Exemplu
17. Să se scrie un program care afişează parametrii din linia de comandă.
#include<stdio.h>
main(int argc, char *argv[])
{ int i;
printf("Fisierul executabil: %s\n", argv[0]);
for(i=1;i<argc;i++)
printf("Parametrul nr. %d: %s\n",i, argv[i]);
}