Jump to content

SUBIECTE NOI
« 1 / 5 »
RSS
Cine canta? Fragment din melodie...

Tablou sigurante Dacia Sandero 2012

Baby Reindeer - 2024

Hotii voteaza hoti?!
 Camera video masina

Zilele emailului din gospodaria n...

Best gaming laptop?

Humane (2024)
 Recomandare casti 100-150 lei

Schimbare bec far VW Touran 1T3

Plata impozit PF

Ce parere aveti de viteza/ modul ...
 Love Lies Bleeding - 2024

Cum sterg mails din Promotions

Vanzare cumparare fara transfer b...

Receptie ciudata, in functie de t...
 

Referințele în C++

- - - - -
  • Please log in to reply
43 replies to this topic

#19
andreim77

andreim77

    Senior Member

  • Grup: Senior Members
  • Posts: 4,235
  • Înscris: 11.04.2006
C nu are suport nativ pt referinte (tipuri built-in) dar de ex. apelul functiilor cu parametri pointeri se cheama ca se face prin referinta la variabilele folosite ca argument.
dar cred ca pentru in incepator e prea confuz conceptul.

#20
tavitu

tavitu

    Minune: HE a început să emită facturile!

  • Grup: Senior Members
  • Posts: 5,598
  • Înscris: 16.02.2009
&variabila - returnează adresă de memorie a variabilei. Valabil în C și C++.

tip date& variabila - declară o variabila referință cu tipul de date respectiv. Valabil numai în C++.

De obicei folosești o referință:
1. Când o funcție trebuie să modifice o variabilă alocată în afara funcției și modificarea trebuie să fie vizibilă în afara funcției, exemplul dat de OriginalCopy.
2. Când o funcție lucrează cu o structură de date foarte mare. Dacă structura de date respectivă este transmisă prin valoare către funcție, mai întâi funcția face o copie privată a structurii de date, lucru care nu este de dorit întotdeauna , în special în cazul în care funcția nu modifică structura de date respectivă sau în cazul în care orice modificări făcute de funcție trebuie să se reflecte în varibila originală.

Ca să dau un exemplu, poți avea un vector<int> cu 100000000 de elemente. Și poți avea o funcție care operează asupra unui vector<int> și numără câte numere impare sunt în vector, sau numere pare, sau află maximul, etc. Dacă transmiți vectorul prin valoare, adică vector<int>, fiecare funcție ar trebui să își facă o copie privată la vectorul de int, cea ce este ineficient, în condițiile în care nu modifică conținutul. Dacă în schimb folosești vector<int>& ca parametru la funcție, nu se copiază tot vectorul, doar referința, iar să copiezi o referență este mult mai rapid decât să copiezi 100000000 de elemente. De asemenea am putea avea o funcție care operează asupra unui vector<int> și înlocuiește fiecare apariție a numărului 13 din vector cu numărul 12, schimbarea trebuie să fie vizibilă în exteriorul funcției, deci este nevoie de o referintă, vector<int>&.

#21
andreim77

andreim77

    Senior Member

  • Grup: Senior Members
  • Posts: 4,235
  • Înscris: 11.04.2006
o mica dar importanta corectie: nu se copiaza referinta la apelul functiei cu parametru referinta, ci se creaza o referinta care e un alias, un nume, o variabila cu un cost nesemnificativ fata de apelul prin valoare a unui super-obiect.

#22
TheOriginals

TheOriginals

    Junior Member

  • Grup: Members
  • Posts: 51
  • Înscris: 30.05.2016
Nu mai ştiu exact pe unde am citit, dar aşa spuneau.

#23
TheOriginals

TheOriginals

    Junior Member

  • Grup: Members
  • Posts: 51
  • Înscris: 30.05.2016

 tavitu, on 31 mai 2016 - 11:11, said:

&variabila - returnează adresă de memorie a variabilei. Valabil în C și C++.

tip date& variabila - declară o variabila referință cu tipul de date respectiv. Valabil numai în C++.

int a=5;
int&b=a;

E chestia asta care ma scoate din minţi...in linia 2 ce se copie în b? adresa sau valoarea? Pentru că dacă am trata exact cum se vede acolo unei adrese îi atribuie o valoare, adică adresa lui b ar trebuie să fie 0x5 să zicem.

#24
andreim77

andreim77

    Senior Member

  • Grup: Senior Members
  • Posts: 4,235
  • Înscris: 11.04.2006
nici, nici, e un detaliu de implementare ce e b in final.
pt tine e un alias, adica un alt nume pentru a.
Similar cu TheO riginals, e un alias pt tine, cand eu string "bai TheO riginals!" te accesez pe tine Posted Image tu esti obiectul propriu-zis catre care refera aliasul TheO riginals. Pe tine te cheama in buletin George sau Ion sau "a" dar pe forum folosesti un alias.

int &b = a; inseamna declararea unui alias pt b, nu are a face cu adresa unui obiect, e o alta utilzare a ampersandului.

de aceea cand zici "b" e ca si cum ai spune "a";
cand vine vorba de pointeri:

int *p = &a;
si
p = &b;

a si b vor fi practic acelasi lucru deci p va indica spre aceeasi variabila/locatie de memorie. la fel:

a=2; si b=2; e fix la fel

a=2; a ia valoare 2

b=3; tot a ia valoarea 3.

Edited by andreim77, 31 May 2016 - 17:34.


#25
TheOriginals

TheOriginals

    Junior Member

  • Grup: Members
  • Posts: 51
  • Înscris: 30.05.2016
Mulţumesc omule...mi-ai luat o piatră de pe inimă în momentul de faţă,
Problema era că & îl vedem peste tot ca o adresă şi mi se pară ciudat că adresei i se atribuia o valoare. Acum am înţeles cum merge.
Mersi încă o dată. :)

#26
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006

 Thefake_fake_fake, on 31 mai 2016 - 10:23, said:

Din ce ştiu eu în C nu există referinţe dar totuşi se foloseşte &valoare. În C "&" are alt rol decât cel de referenţiere? Aici mă refer de exemplu la citirea
&-ul ala din C la care te referi tu e si in C++.

Dar pe el, ca si pe cel din C++, il folosesti atunci cand apelezi o functie, nu in semnatura functiei, si are o semantica diferita.

Din nou, trebuie sa faci diferentierea dintre "a citi o variabila" sau "a scrie intr-o variabila", analog cu ce ti-am spus ieri: in partea stanga a egalului te intereseaza adresa unei variabile, in partea dreapta te intereseaza valoarea ei.

In exemplul de ieri in C++, & era in semnatura (antetul) functiei, aveai void max(int&), aici e vorba de referentiere. Aceasta sintaxa nu exista in C. pentru ca C nu are referinte asa cum sunt ele definite in C++.

In C, la exemplul cu scanf, & il pui la apelarea functiei (aici: scanf), caci scrii: scanf("...", &a); --- observi unde e &?

In ambele limbaje, & in operatiile de citire are aceeasi semantica: adresa unei variabile. int* a = &b; // salveaza in a valoarea lui &b, adica adresa la care e alocata static variabila b.

void max(int&); /// nu este o sintaxa valida in C, doar in C++.

Din nou, fa diferenta dintre operatiile de citire si de scriere. Acest &:

int* a = &b;

vs acest &:

int& a = b;

Sper ca observi ca sunt lucruri diferite.

Reluand aceasta idee:

 OriginalCopy, on 31 mai 2016 - 18:13, said:

analog cu ce ti-am spus ieri: in partea stanga a egalului te intereseaza adresa unei variabile, in partea dreapta te intereseaza valoarea ei.
e logic ca orice ai in partea dreapta a egalului, doar ii accesezi valoarea, da?

adica ori ca pui asa:

int a = 42;

ori asa:

int a = b;

in dreapta se afla o valoare.

Intrebare: cum faci sa fortezi compilatorul sa evalueze ce e in dreapta ca adresa, nu ca valoare? Exact, pui &.

int a = &b;

Dar acum ai o problema: tipurile de date difera, in stanga ai int, in dreapta ai un intreg de marimea busului de adrese din CPU, deci ai in schimb:

int* a = &b;

Sper ca acum ti-ai mai dezvoltat intuitia fata de pointeri.

#27
andreim77

andreim77

    Senior Member

  • Grup: Senior Members
  • Posts: 4,235
  • Înscris: 11.04.2006
Lol the fake fake fake :)

On: e un concept specific, aceeasi entitate folosita in diverse scopuri: & e folosit pt referinte, adresa unei variabile si ca operator si pe biti. Se cheama supraincarcare sau polimorfism static desi termenul asta e folosit mai mult in oop, dar mai ai pana ajungi acolo.

#28
TheOriginals

TheOriginals

    Junior Member

  • Grup: Members
  • Posts: 51
  • Înscris: 30.05.2016
Daca am int *p;
int x=3;
Nu ştiu dacă e corect dar în mintea mea e o diferenţă între p şi *p;
* e volosita pentru a afişa valoarea conţinută de adresa pointerului p.
Dacă ii dau p=&x o să se modifice adresa conţinută de pe şi nu adresa lui p la care este stocat el nu?
Am aici o imagine cum văd eu pointerii..e ok?
[ http://s33.postimg.org/iig9lct1b/point.png - Pentru incarcare in pagina (embed) Click aici ]
greenshot

Mai ignoraţi din comentarii...am făcut desenul când mă chinuiam eu să înţeleg.
Cand spre exemplu îi dai *p=&x, se modifica adresa care o contine p si o să indice spre x..dar când doreşti să-i afişezi valoarea faci tot cout<<*p;
Adică când îl foloseşti = se modifică adresa conţinută de variabila de tip pointer, iar când foloseşti cout afişează valoarea conţinută de adresă...cu toate că în ambele cazuti foloseşti *p

Edited by TheOriginals, 31 May 2016 - 18:52.


#29
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
"nu mi se pare corect sa folosesti *p = &a" - da, gandesti bine, nu se foloseste * in acel context, ci p = &a.

Greseala ta e ca lipesti (mental) * de variabila, si asta se vede si din cum formatezi codul. Acel * nu ii apartine variabilei, ci tipului de date.

Daca te uiti la postarile mele, am scris mereu:

int* p = &a;

si nu:

int *p = &a;

Deoarece int* este un tip de date - il scriu impreunat.

Ar trebui sa adopti acest stil de a formata codul, desi si int *p e corect, pana iti insusesti intuitia in mod corect.

La fel si:

int& a = b;

e mai bine decat:

int &a = b;

<tip de date, oricare ar fi el> <identificator> = <valoare> e de fapt o scriere compacta pentru "doua" operatii:

1. alocarea statica a variabilei:

<tip de date, oricare ar fi el> <identificator>;

ex:

int a;

2. copierea unei valori la acea adresa:

<identificator> = <valoare>

ex:

a = 42;

Asadar:

int* p = &a;

este prescurtarea pentru:

int* p;
p = &a;

Acest mod de alipire a operatorilor unari gen * sau & de tipul de date e consistent si cu declararea de functii (doar antetul). In antet nu trebuie decat sa declari tipul de date, nu si identificatorul, deoarece dupa un antet nu mai urmeaza si implementarea functiei, ci direct ;

int max(int*, int);

int main() {
  //... aloca un array a de marime size)
  cout << max(a, size);
  return 0;
}

int max(int* data, int size) {
 // for loop over size memory cells of sizeof(int) starting at address data)
 //return maxim
}



#30
TheOriginals

TheOriginals

    Junior Member

  • Grup: Members
  • Posts: 51
  • Înscris: 30.05.2016
Acum are mult mai mult sens, mai ales că mi-ai atras atenţia asupra chestiei cu int* a.
Mai am o chesti care nu îmi este clară:
Am doua variabile
x=5;// adresa lui x este 0x12
*p;//adresa lui p este 0x13
int* p = &a;//daca fac asta se traduce prin: adresa continută de p o sa fie = cu adresa lui a (adică noua adresă la care referă p o să fie 0x12)

Adică cum văd eu chestia la momentul de faţă prin intermediul operatorului * s-a modificat adresa, dar când îl foloseşti în cout (cout<<*p) afişează valoarea. (După părerea mea se bat cap în cap..o dată prin intermediul * modific adresa spre care pointează variabila, iar când îl folosesc în cout afişează valoarea pointată de adresă)
* se comportă diferit la cout?
Adică de ce o dată prin intermediul * i-am modificat o adresă iar în cout el interpretează acea adresă şi afişează valoarea (în cauză fiind aceiaşi operator *)?

#31
Mosotti

Mosotti

    Geniu umil

  • Grup: Senior Members
  • Posts: 33,295
  • Înscris: 21.04.2004

Quote

Daca am int *p;
int x=3;
Nu ştiu dacă e corect dar în mintea mea e o diferenţă între p şi *p;

* din

int *p;

e total altceva decit * din

*p

Vezi tu, limbajul asta e cretinel in esenta lui, de fapt este

int* p;

adica "pointer la int" dar el, limbajul cretinel, permite sa scrii acel gunoi de asterisc oricum

int* p;
int * p;
int *p;



chiar si

int									*						p;

toate sint valide, pentru ca Satan, creatorul limbajului, a vrut sa-l faca cit mai imposibil pentru incepatori...

Cica motivul pentru care se foloseste asa de mult varianta cu asterisc linga variabila in loc de tip este ca daca declari mai multe variabile pe aceeasi linie si nu pui linga fiecare cite un asterisc, doar prima e pointer, adica

int* a, b, c; // doar a e pointer

int *a, *b, *c; // toti este ponteri (limbaj de manelist)



Deci ca sa revenitm tu cind zici

int * p = 3 nu e nici pe departe ce zici tu in imaginea aia, nici macar nu compileaza... incerci sa atribui un "int" unui "pointer la int"

Ca sa faci ce vrei tu tre sa faci:

int* p = new int;
*p = 3;



Pe de alta parte, * din *p se numeste dereference operator, dracu stie cum se traduce asta in romana, si face ce zici tu in imaginea aia...

#32
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
Eu zic sa bagi pe google: ted jensen pointers tutorial si sa iei la rand toate exemplele de acolo si - foarte important - sa le tastezi tu cu mana ta de la zero, pentru ca in timp ce tastezi cod intelegi altfel ce cod scrii, si sa nu dai copy/paste la cod.

Unul din exemplele din acel tutorial este de genul:
	 1 #include <stdio.h>
	 2 #include <stdlib.h>
	 3
	 4 int main() {
	 5	 int* p;
	 6	 int a;
	 7	 printf("variable a is allocated statically at address %p and has garbage value %d\n", &a, a);
	 8	 printf("variable p is allocated statically at address %p and points to garbage address %p\n", &p, p);
	 9	 //copying value 42 to address &a
	10	 a = 42;
	11	 // store the value &a at address &p
	12	 p = &a;
	13	 printf("variable a is allocated statically at address %p and has value %d\n", &a, a);
	14	 printf("variable p is allocated statically at address %p and points to address %p\n", &p, p);
	15	 printf("now it is safe to dereference pointer p because it does not point to garbage: %d\n", *p);
	16	 return EXIT_SUCCESS;
	17 }
	18


Fii foarte atent la valori si fa corelatii.

Atentie la ce ti-am spus ieri: toate sunt variabile, pointerii sunt in primul rand variabile, referintele la fel. Si ti-am mai spus si ca toate variabilele au o adresa, un identificator, o valoare, si un tip de date. ASADAR, si pointerii au o adresa.

PS: in realitate compilatorul poate face tot felul de optimizari, insa ele sunt irelevante pentru ca tu ca incepator sa intelegi cum functioneaza lucrurile - ba mai mult te-ar incurca in procesul de intelegere.

Edited by OriginalCopy, 31 May 2016 - 19:36.


#33
TheOriginals

TheOriginals

    Junior Member

  • Grup: Members
  • Posts: 51
  • Înscris: 30.05.2016
Ok, asta e cartea https://pdos.csail.m...gs/pointers.pdf ?

#34
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006

 Thefake_fake_fake, on 31 mai 2016 - 19:35, said:

Da. Incearca mai intai codul pe care ti l-am arata, iti raspunde la unele nedumeriri (cred eu).

#35
TheOriginals

TheOriginals

    Junior Member

  • Grup: Members
  • Posts: 51
  • Înscris: 30.05.2016
ok, cred că am înţeles, oricum am să citesc ce mi-ai lăsat pentru că din ce văd e explicat şi bine şi nici nu e voluminoasă.
Mersi

//update :))
Tu-i în aripă de pointeri..pot să spun că tocmai s-a făcut lumină. Acum sper să nu vă mănânc nervii şi mâine cu întrebări după ce termin de citit cartea. ;))

Edited by TheOriginals, 31 May 2016 - 20:25.


#36
andreim77

andreim77

    Senior Member

  • Grup: Senior Members
  • Posts: 4,235
  • Înscris: 11.04.2006

Quote

adica "pointer la int" dar el, limbajul cretinel, permite sa scrii acel gunoi de asterisc oricum

c++ e un limbaj f puternic, probabil cel mai complex, care iti permite sa faci orice dar si sa distrugi orice daca nu ai grija. Si C permite acelasi lucru.

ia uite de ex. cum arata man strcpy in linux:

#include <string.h>
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);

Mai exact unde au pus steluta. Iar baietii care au scris linux si man sunt mai destepti ca noi.
Accentul e pe faptul ca variabilele sunt pointeri. Un argument egal cu al tau, ca vrei tipul complet scris compact. E aceeasi discutie ca while(*p++ == *q++) {}, unora le place altora nu, dar cine pricepe subtilitatile limbajului indeajuns, va sti valoarea unei astfel de expresii.

Steluta poate fi pusa oriunde, langa tip, variabila sau cu spatii intre ambele pt ca limbajul e "free form", asa cum cred ca e orice limbaj de nivel inalt. Prin nivel inalt nu se intelege ca-i valoros ci e apropiat de limbajul uman (nu am alta explicatie mai clara acum Posted Image ).

Edited by andreim77, 01 June 2016 - 09:45.


Anunturi

Bun venit pe Forumul Softpedia!

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Forumul Softpedia foloseste "cookies" pentru a imbunatati experienta utilizatorilor Accept
Pentru detalii si optiuni legate de cookies si datele personale, consultati Politica de utilizare cookies si Politica de confidentialitate