Aceasta scurta istorie e despre unicul lucru constant din univers - schimbarea... Ce ar fi daca pi era diferit de 3.14...? Si daca e ar fi fost diferit de 2.71...? Si daca phi era altceva decit 1.618...? Astazi nu voi discuta despre aceste lucruri, ci voi discuta despre const in C ;-)
When modifying a data declaration, the const keyword specifies that the object or variable is not modifiable. When following a member function's parameter list, the const keyword specifies that the function doesn't modify the object for which it is invoked.
Da? Sau poate totusi e posibil?
const int c=5;
int *p, b;
p=(int*)&c;
*p=3;
b=*p; //b=3
b=c; //b=5
b=*(int*)&c; //b=3
Ce se petrece aici? p este un pointer care ia adresa constantei c, si apoi se modifica continutul acelei adrese de memorie spre care point'uieste p. Cu alte cuvinte, daca ne uitam cu debuggerul, vedem urmatoarele:
- p si c au aceeasi adresa
- deci au si aceeasi valoare (in cazul de fata, constanta c, care era cindva =5, acum este =3)
- dar, cum credeti ce valoare primeste b dupa b=c?
Mda... valoarea lui b este 5, si nu 3. E natural sa ne intrebam ce se petrece, si cum se explica aceasta.
Sa incercam in alta parte, cu un alt compilator, pe un alt OS. Aici se petrece acelasi lucru - continutul memoriei se modifica, dar cind folosim undeva constanta, valoarea este oricum acea 'constanta', si nu acea pe care am modificat-o artificial.
Pina la urma s-a ajuns la concluzia ca ceva nu e in regula... Sau noi ne-am timpit, sau lumea intreaga e nebuna ;-) Sapind un pic mai adinc, s-a ajuns la concluzia ca acea memorie in care se stocheaza valoarea constantei nu este utilizata. De fapt, daca codul este dezasamblat, totul devine evident - peste tot valoarea constantei este 'hard coded', adica in nici unul din cazuri nu se citeste nici-o adresa de memorie, ci se transmite direct o valoare; de parca undeva in cod s-a scris #define c 5
De fapt, asa am si facut:
#define HZ_ 5
int _tmain(int argc, _TCHAR* argv[])
{
const int c=5;
int *p, b;
p=(int*)&c;
printf("%i ", c);
*p=3;
b=*p;
b=c;
b=HZ_;
Si iata cum arata aceasta la nivel inferior:
- vedem ca valoarea 5 se transmite 'as is', fara de a fi citita de undeva. Aceasta explica de ce vedem ca memoria alocata pentru c a fost modificata, pe cind orice incercare de a folosi valoarea lui c arata ca nu s-a schimbat nimic;
- vedem ca b=c si b=HZ_ este absolut acelasi lucru;
- screenshotul facut in Linux arata si el codul de nivel inferior. Sintaxa AT&T este mai putin frumoasa (cel putin dupa parerea mea), dar se vede si acolo ca 5 se transmite fara de a fi citit de undeva.
Deci, care sunt concluziile?
- Presupunerea ca pentru constante se alocheaza o memorie speciala, care se foloseste pentru a stoca valorile 'adevarate' a constantelor a fost falsa. Daca ar fi fost asa, inseamna ca o aplicatie care foloseste multe constante, consuma si un volum mai mare de memorie;
- Valoarea constantei poate fi modificata, si nu poate fi modificata in acelasi timp. Experimentul a aratat ca se modifica memoria in care se stocheaza constanta, insa acea memorie nu se utilizeaza. In ultima linie din primul fragment de cod, valoarea lui c se citeste 'fortat' din memorie, si atunci vedem ca totusi e valoarea modificata.
Si daca tot suntem aici si discutam despre C:
int z[3]={1,2,3};
b=z[0];
b=1[z];
Ce se intimpla in linia #3? Se intimpla b=z[1]. De ce? Pentru ca un array este de fapt un pointer, iar un pointer este de fapt un array.
b=z[0] este echivalentul b=*(z+0), iar b=z[1] este echivalentul b=*(z+1), iar b=*(1+z) este acelasi lucru ;-)
Nota: pointer arithmetic este o chestie care difera de asteptarile unui om non-initiat in C. Spre exemplu, z+3 nu te duce la z + offset de 3 bytes, ci la z + 3*sizeof(z) bytes (z e int, deci se face 3*sizeof(int), adica ne deplasam nu cu 3 bytes, ci cu 3 valori intregi mai departe). De fapt, daca citesti aceasta pagina, atunci nota data ar trebui sa-ti fie cunoscuta. ;-)
Acum ramine sa speram ca universul este un sistem extrem de fiabil, in care constantele sunt 100% constante :-)
Post:
int z[3]={1,2,3};
b=z[0];
b=1[z];
ai aici in ultimul rind o eroare :)
I hope you can see it
In rest articolul e destul de interesant.
Si pentru e destul de informativ :)
Thx for what u doing. See ya!