Jump to content

SUBIECTE NOI
« 1 / 5 »
RSS
"Moda" tinerilor care se ...

E.on energie aplicație intre...

Masina de tuns... buruieni

Recomandare drona
 Exista un soft care sa reia autom...

Identificare plante

Cum declari o variabila care nu s...

Schimbare certificat de inmatricu...
 Poligon auto București

nelamurire legata de pret la mode...

Hotel cu restaurant si Demipensiu...

Croaziera in Mediterana de Vest 1...
 Copilot are pica pe Vladimir Putin

MicroSoft Edge: Cum pun Google in...

Dashcam

Mini server - VMware
 

Utilizarea pointerilor – Aplicații propuse

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

#1
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,241
  • Înscris: 24.02.2007
Observ ca multi intampina probleme atunci cand isi insusesc notiunea de pointeri. Drept urmare, deschid acest topic pentru a propune diverse probleme ce au la baza pointeri pentru a ajuta lumea sa ii inteleaga mai bine.

Probleme sunt inspirate in mare parte din cazuri reale de utilizare asa ca nu va speriati daca mai intalniti si elemente straine.

Cum doresc sa se desfasoare activitatea aici:
  • Oricine poate propune probleme. Preferabil creatie proprie, dar, daca nu, macar sa fie indicata sursa.
  • Fiecare problema va fi inserata intr-un post nou si va fi insotita de ceva explicatii cu privire la ce se urmareste si de ce e important/util sa se procedeze asa.
  • Fiecare problema va avea un cod de identificare pentru a se putea fi mentionata in rezolvari. De preferat ceva cod random si nu numere crescatoare.
  • Pentru a nu polua acest topic, solutiile propuse vor fi introduse aici: http://forum.softped...211;-rezolvari/

A few tips cu privire la lucrul cu pointeri:
  • Un pointer e o valoare numerica ce retine o adresa din memorie. Se poate face analogia cu numarul unei case la strada, numarul unui dosar intr-un raft, etc.
  • In memorie, un pointer ocupa fix atata spatiu, pe cat este arhitectura procesului in cauza (32 biti pentru procese 32 bit, 64 pentru procese pe 64 bit, etc)
  • Singura diferenta intre int* si char* este ce se asteapta compilatorul sa gaseasca la acea adresa. Astfel, la dereferentiere, int* x = ...; int y = *x, el va citi sizeof(int) bytes de la adresa indicata de x si ii va interpreta drept int. Deasemenea, int* x = ...; x += 1 va avansa adresa cu sizeof(int) bytes, nu cu o unitate.
  • int x[3] e tot un pointer, x indicand spre adresa din memorie a primului element. Fata de int* x nu permite insa schimbarea adresei: x = altceva.
  • Cand avem int* x putem accesa x[4], ca si cum am fi avut int x[5] (*x == x[0]; *(x+1) == x[1]). Trebuie avuta insa grija daca blocul de memorie se intinde suficient de mult.
  • Lucrul cu pointeri e unul, managementul memoriei e altceva. Se poate lucru cu pointeri folosind memoria deja alocata, nu trebuie fiecare problema sa fie plina de malloc/free/new/delete.

553702AA - Iterarea prin valorile stocate in memorie

Sa se realizeze o functie ce primeste drept parametru un pointer la o adresa din memorie la care sunt stocate numere intregi (int) si un numar reprezentand cate elemente se gasesc la acea adresa.
Functia va citi toate elementele si va returna media aritmetica a acestora (rotunjita).


Nu se va aloca dinamic memorie.

Astfel se exerseaza ceva fundamental: citirea unei valori din memorie.

52A37342 - Iterarea prin valorile stocate in memorie pana la intalnirea unei valori predefinite

Sa se realizeze o functie ce primeste drept parametru un pointer la o adresa din memorie la care sunt stocate numere intregi (int).
Functia va citi toate elementele, pana intalneste primul 0, si va returna media aritmetica a acestora (rotunjita).


Nu se va aloca dinamic memorie.

Astfel, lumea va intelege aceasta abordare adesea folosita in cazul sirurilor de caractere. Functii precum strlen accepta drept parametru doar un pointer, nu si numarul elementelor. Ele stiu cand sa se opreasca dupa conventia de a avea un 0 la finalul sirului.

FFAA5B72 - Reinterpretarea memoriei

Deobicei un float ocupa tot 4 bytes, ca un int. Insa unul retine un numar intreg iar celalalt o valoare cu virgula. Memoria fiind limitata, numarul de valori este deasemenea limitat (spre deosebire de matematica unde avem o infinitate de valori intre 0 si 1).

Sa se afle cate valori intre -1 si -2 (inclusiv) se pot reprezenta intr-un float. Practic veti itera prin toate valorile unui unsigned int, veti interpreta zona respectiva de memorie ca un float si veti numara cate valori sunt intre -1 si -2 (inclusiv).

Inspirata de aici: http://stackoverflow...ally-this-smart

Edited by dani.user, 07 June 2015 - 12:04.


#2
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,241
  • Înscris: 24.02.2007
9462318E - Utilizarea pointerilor pentru returnarea datelor

Cel mai adesea, in practica, pointerii sunt utilizati pentru a pasa date dintr-o parte in alta. Atunci cand ne asteptam ca o functie sa ne returneze ceva, se prea poate ca functia sa ne ceara un pointer spre o zona din memorie unde sa ne depoziteze rezultatele.

Sa se realizeze o functie ce returneaza primele n numere prime mai mici decat N. Functia va primi drept parametrii numarul de numere prime solicitate (n), valoarea maxima (N) si un pointer la o zona de memorie unde va scrie numere prime returnate. Functia va returna apoi cate numere a scris in acea zona de memorie. Functia presupune ca a fost alocata suficienta memorie pentru a retine cele maxim n numere solicitate.

Se poate observa o similitudine intre aceasta functie si fread(). Si lui fread() ii spunem unde sa scrie rezultatul si cat de mare poate fi rezultatul acceptat.

Unii va veti intreba: de ce nu returneaza functia direct un pointer la zona de memorie continand rezultatul? Pare o idee buna la prima vedere, dar are un mic inconvenient: cineva aloca memoria (functia) si altcineva trebuie s-o elibereze (utilizatorul functiei); iar pentru a putea elibera trebuie sa stii cum a fost alocata. Asadar functia ar trebui sa mentioneze in documentatie cum anume trebuie eliberata memoria iar utilizatorul sa fie mereu atent la acest detaliu.
Cerinta propusa rezolva aceasta problema prin faptul ca revine utilizatorului intreaga responsabilitate de a gestiona memoria. Functiei nu ii pasa cum a obtinut cel ce o cheama memorie pentru a depozita rezultatele.

#3
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,241
  • Înscris: 24.02.2007
70BD4884 - Utilizarea unei functii existente (Windows) ce returneaza date prin intermediul pointerilor

In cazul exercitiului 9462318E am vazut cum se creaza o functie ce depoziteaza rezultatele acolo unde ii cere utilizatorul. Acum e cazul sa utilizam una creata de altii ce functioneaza pe acelasi principiu.
Spre deliciul celor satui de aceleasi probleme pline de calcule numerice, functia aleasa pentru acest exercitiu va returna ceva cat se poate de concret: numele calculatorului.

Sa se scrie o aplicatie ce afiseaza numele calculatorului curent, nume obtinut prin apelarea GetComputerName.
Documentatia din link explica exact ce parametrii accepta functia, ce returneaza; inclusiv in ce header e declarata.

O mica observatie pentru cei nefamiliarizati cu API-ul Windows:
  • Nu exista functia efectiva GetComputerName ci exista doua variatii ale sale: GetComputerNameA si GetComputerNameW. Aceastea opereaza fie cu caractere normale (char), fie cu cele wide (wchar_t).
  • GetComputerName este un macro ce se expandeaza la GetComputerNameA in mod normal sau la GetComputerNameW daca e definit macro-ul UNICODE
  • TCHAR este sinonim cu char cand UNICODE nu e definit, sau wchar_t cand UNICODE e definit.
  • LPTSTR e sinonim cu TCHAR*

Pe scurt, daca nu vreti sa intrati in detalii din aceastea, apelati direct GetComputerNameA pasand un pointer la char drept prim argument.

#4
OriginalCopy

OriginalCopy

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

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
C2BFAA9D - Pointeri la functii I - refolosirea unui algoritm pentru diferite tipuri de date

Sa ne imaginam un concurs pe echipe la care participa mai multi elevi. O echipa e formata dintr-unul sau mai multi elevi, si fiecare elev are o anumita experienta mai mare de 0 dar mai mica de 256 in joc. Un elev nu isi poate reprezenta echipa mai mult de o data.

Biblioteca standard C contine functii care pot fi parametrizate cu alte functii: bsearch() si qsort().

Data fiind structura de date:

typedef struct _student {
  char *name;
  char *team;
  unsigned char experience;
} student;


scrieti un program care foloseste aceste doua functii pentru a determina numele candidatului care trebuie sa concureze pentru o echipa data astfel incat sansele de reusita ale echipei sa fie maximizate.

Elevii (numele lor, echipa din care fac parte, si experienta lor in joc) vor fi introdusi de la tastatura intr-o ordine aleatorie, apoi se va cere introducerea de nume de echipe, iar apoi se va printa numele celui mai bun candidat pentru acea echipa.

Programul se va termina atunci cand utilizatorul nu introduce un nume de echipa, eliberand toata memoria de pe heap ocupata.

Edited by OriginalCopy, 09 June 2015 - 18:49.


#5
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,241
  • Înscris: 24.02.2007
F86EDD04 - Pointeri la functii - threads & callbacks

Pointerii la functii se folosesc adesea cand un cod extern doreste sa apeleze codul nostru la un moment dat. Folosind fire de executie (threads) se poate obtine executia unei functii in paralel cu alta.

Sa se realizeze o aplicatie ce cauta numere prime in ordine crescatoare timp de doar 2 secunde, iar apoi afiseaza cate a reusit sa gaseasca.

Aplicatia va folosi doua fire de executie, unul cautand numerele prime, iar celalalt asteptand sa treaca doua secunde notificand apoi primul ca a expirat timpul.
Functiile folosite sunt specifice sistemului de operare:
Windows: Sleep, CreateThread
*nix: sleep, pthread_create

#6
dani.user

dani.user

    Guru Member

  • Grup: Senior Members
  • Posts: 30,241
  • Înscris: 24.02.2007
30A206F1 - Implementarea polimorfismului folosind pointeri la functii

Acum ca lumea a prins curaj si incepe sa se descurce in ce priveste utilizarea pointerilor, propun urmatorul exercitiu:

Sa se realizeze un sistem ce permite altor programe sa fie notificate cand se modifica cursul valutar, tinand cont de cele de mai jos.

  • Aplicatia va fi scrisa in C, fara ++, insa va fi implementata orientat pe obiect. Asa veti intelegi si ce face C++-ul behind the scenes
  • Cursul valutar va fi citit din cel putin doua locuri (valori aleatoare din memorie, de pe disc, de pe net). Pentru simplificare, e suficient eur/ron si usd/ron.
  • Sistemul de notificare va fi folosit in stilul urmator:
    void modificareCursValutarEur(float ronPerEur)
    {
       printf("S-a schimbat cursul. Acum 1 EUR = %f RON.", ronPerEur);
    }
    
    int main() 
    {
       ...
       IExchangeRateRetriver* retriever = CreateFileRetriever("D:\\curs_valutar.txt");
       ExchangeRateNotification* notificationService = CreateNotificationService(10, retriever); //10 secunde - intervalul la care serviciul va verifica daca s-a schimbat cursul. 
    
       AddNotificationHander(notificationService, "EUR-RON", modificareCursValutarEur); //solicit ca modificareCursValutarEur sa fie apelata de fiecare data cand se schimba cursul
       DoWork(notificationService); //urmareste cursul pana la alte indicatii
    }
    
    
  • Serviciul de notificare e practic un timer care, odata la X secunde, cere cursul valutar, compara valorile cu cele precedente, iar, daca s-a inregistrat vreo modificare, iar cineva e abonat sa fie anuntat de acea modificare, cheama respectiva functie pasandu-i noua valoare a cursului.
  • Partea interesanta apare in modul in care serviciul de notificare preia cursul valutar, mai exact cum va arata structura IExchangeRateRetriver.

    Serviciul de notificare va interoga un alt obiect pentru a afla exact valorile noului curs. Serviciului de notificare nu ii pasa de unde primeste valorile cursului, ele pot veni dintr-un fisier de pe disc, de pe net, etc.

Am scris mai sus ca e vorba de o structura IExchangeRateRetriver, nu un simplu pointer la functie. De ce? Fiindca e nevoie de o stare.
  • Daca serviciul de notificare ar apela doar ceva de genul, newRate = retriever();, functia ce preia cursul, din fisier, n-ar avea de unde sa stie ca se doreste citirea sa din curs_valutar.txt. Da, s-ar putea stoca ca o variabila globala, insa poate aplicatia vrea sa citeasca din mai multe fisiere.
  • Daca serviciul de notificare ar apela doar ceva de genul, newRate = retriever(cale_pe_disc);, poate ar fi ok pentru citirea de pe disc, dar poate pentru citirea de pe net e nevoie si de alti parametrii.

Prin urmare, IExchangeRateRetriver trebuie gandit in asa fel incat sa poate fi extins cu citirea de oriunde, fara ca serviciul de notificare sa trebuiasca sa fie modificat.
Daca apelez codul de mai jos, totul ar trebui sa mearga la fel de bine, fara sa modific nimic altceva, in afara de detaliile CreateNetRetriever si ce returneaza. Mai exact, totul codul legat de notification service va ramane la fel.
   IExchangeRateRetriver* retriever = CreateNetRetriever("http://www.site.ro", "ion", "parola_mea");
   ExchangeRateNotification* notificationService = CreateNotificationService(10, retriever); //10 secunde - intervalul la care serviciul va verifica daca s-a schimbat cursul. 


Aici intervine polimorfismul.

BONUS: Daca reusiti implementarea in C, creati si una in C++, si, desigur, si citirea cursului de pe net.

Edited by dani.user, 12 July 2015 - 17:10.


Anunturi

Chirurgia endoscopică a hipofizei Chirurgia endoscopică a hipofizei

"Standardul de aur" în chirurgia hipofizară îl reprezintă endoscopia transnazală transsfenoidală.

Echipa NeuroHope este antrenată în unul din cele mai mari centre de chirurgie a hipofizei din Europa, Spitalul Foch din Paris, centrul în care a fost introdus pentru prima dată endoscopul în chirurgia transnazală a hipofizei, de către neurochirurgul francez Guiot. Pe lângă tumorile cu origine hipofizară, prin tehnicile endoscopice transnazale pot fi abordate numeroase alte patologii neurochirurgicale.

www.neurohope.ro

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