Thursday, December 31, 2015

Limbajul C++. Implementarea unei functionalitati aritmetice intr-o clasa

Exemplul urmator propus de programmr.com are un singur aspect netrivial: se cere ca initializarea membrilor clasei sa se faca prin metode, si nu prin explicitarea constructorilor.

Clasa student invocata in enunt are trei membri - un string care prezerva numele studentului, un integer pentru matricola si un tablou de intregi pentru notele la cinci materii.

O metoda publica input initializeaza membrii dupa instantierea unui obiect student. O alta metoda publica output afiseaza media notelor.

Enuntul original:

"A class student has three data members: name, roll, marks of 5 subjects and member functions to input name, roll no and marks, and display Percentage. Declare the class student and define the member functions. The program should ask user for name, roll no and marks in 5 subjects, and should display the percentage."

Codul si printscreen-ul:

Limbajul C++. Alte probleme cu siruri de caractere

Doua enunturi fara mari dificultati de pe programmr.com, cu mentiunea ca am folosit pentru initializarea sirurilor de caractere, in locul "batranei" functii gets(char *str) din biblioteca C, metoda getline din clasa std::istream. 

Aceasta incarca in spatiul indirectat de char * str un numar specificat, n, de caractere inclusiv terminatorul de sir. Adica, daca dorim sa impunem citirea a maxim 50 de caractere, linia corespunzatoare va fi:

cin.getline(str, 51);

Primul enunt cere scrierea unui cod care converteste fiecare caracter al unui sir de caractere in echivalent binar, fiind luate in calcul si eventualele spatii si semne de punctuatie.

O functie de conversie realizeaza 8 impartiri la 2 ale codului ASCII corespunzator fiercarui caracter transmis ca parametru, pentru a initializa bitii care codifica respectivul caracter, stiut fiind ca o variabila de tip char ocupa 8 biti in memorie.

Codul si printscreen-ul:

Wednesday, December 30, 2015

Limbajul C++. Capitalizarea literelor sau o problema stil K & R


Un exemplu de cod care numara cuvintele intr-un sir de caractere este prezentat in cartea scrisa de Kernighan si Ritchie.

Enuntul urmator, "Write a program which takes input string and capitalizes the first character of each word in a string, and does not affect the others"  este de pe site-ul programmr.com, dar cu siguranta poate fi intalnit in multe alte locuri/lucrari.

Rezolvarea problemei se bazeaza pe acelasi mecanism descris in lucrarea lui K & R:

- definirea unui cuvant ca o succesiune de caractere non-space care sunt bordate de spaces. Desigur, pe baza acestei definitii, ,,,#@sg-abcd,, este un cuvant, ceea ce poate parea derutant in raport cu bunul simt. Desigur, asd_g def este, conform aceleiasi definitii, o succesiune de doua cuvinte, asd_g si def.

- declararea si setarea unei variabile inword  care "tine cont" daca la un moment oarecare (la o iteratie oarecare) ne aflam sau nu in interiorul unui cuvant.

Daca s este un sir de caractere introdus de la tastatura, a carui lungime length o vom determina, atunci algoritmul implementat poate fi urmatorul:

Tuesday, December 29, 2015

Limbajul C++. Implementarea unei aplicatii cu clase derivate


Urmatorul enunt reprezinta un assignment aferent uneia dintre lectiile din cadrul cursului "Bazele programarii C++" sustinut la InfoAcademy.

Aceasta prezentare nu are intentia de a compromite procesul didactic, ci de a oferi o perspectiva asupra felului in care sunt prezentate in viata reala cerintele de implementare a unui proiect.

Enuntarea si implementarea cerintelor sunt abordate pas cu pas.

Se lucreaza intr-un spatiu de nume intitulat "Assignment9".

Declaratiile de clase sunt salvate in fisiere header (.h). Definitiile sunt salvate in fisiere sursa (.cpp).

Limbajul C++. Clonarea obiectelor folosind metodele virtuale si constructorul de copiere


Realizarea unei clone a unui obiect presupune crearea unui obiect nou, cu existenta independenta de cel clonat, care ocupa in memorie un spatiu distinct de cel clonat dar care are toate atributele si metodele identice cu ale celui clonat.

Mecanismul urmator foloseste constructorul de copiere si o metoda declarata virtuala, care este supracrisa in clasa derivata. Declararea virtuala este necesara pentru apelul corect al metodelor: metoda Clone va fi cautata intai in clasa derivata, indiferent de scenariu - fie ca variabila are tipul clasei de baza sau cel al clasei derivate.

Stim ca o variabila initializata cu o instanta a clasei derivate are si tipul clasei de baza (invers nu!)

Suprascrierea metodei implica prezervarea aceleiasi semnaturi (nume, argumente, tip de return) dar o implementare diferita in clasa derivata.

Sunday, December 20, 2015

Limbajul C++. Functii. Transfer prin valoare, referinta, adresa


Stim ca la transmiterea prin valoare a argumentelor unei functii, prelucrarea nu se face asupra variabilelor-argument, ci asupra unor copii. Copiile sunt variabile interne blocului functiei, de aceea durata lor de viata este limitata la blocul functiei. Reguli:

1) nu folosim transmisia prin valoare in cazul unor variabile de mari dimensiuni, pentru ca dimensiunea trebuie replicata pentru copiile folosite in corpul functiei;

2) nu folosim transferul prin valoare cand vrem ca variabilele transmise ca argument sa fie modificate.

Pentru cazurile mentionate anterior putem folosi transferul prin referinta (alias al variabilei-argument, permis doar in C++) sau transferul prin adresa (cu pointeri, permis in C/C++). 

Transferul prin adresa este, de fapt, tot un transfer prin valoare.

Tuesday, December 15, 2015

Limbajul C. Sortarea unei liste

Este vorba despre o lista simplu inlantuita (LSI), ale carei noduri servesc drept container pentru valori numerice (numere intregi in cazul de fata). Sigur ca se poate obiecta ca e un efort inutil sa scrii cod pentru a sorta secvente de numere intregi folosind structuri, recte LSI. 

Exista varianta binecunoscuta de sortare folosind vectori sau tablouri monodimensionale drept container.

Totusi, structura fiind un tip de data definit de utilizator, este mai flexibila decat un tablou, fie si prin faptul ca un nod al listei, spre deosebire de elementul unui tablou, poate contine mai mult de o variabila de baza la un moment dat.

Ne putem imagina, de pilda, o LSI care stocheaza in fiecare nod trei intregi corespunzand unei date calendaristice: ziua, luna, anul.

Intr-un astfel de caz, LSI este optiunea naturala, in detrimentul celei cu tablouri.

Sortarea unei astfel de liste ar trebui gandita dupa urmatorul algoritm: