This shows you the differences between two versions of the page.
poo-is-ab:laboratoare:02 [2025/09/24 21:07] razvan.cristea0106 [Diferențe C/C++] |
poo-is-ab:laboratoare:02 [2025/10/04 18:30] (current) razvan.cristea0106 [Concluzii] |
||
---|---|---|---|
Line 12: | Line 12: | ||
==== Introducere ==== | ==== Introducere ==== | ||
- | În cadrul acestui laborator vom evidenția principalele diferențe dintre limbajele C și C++. Vom analiza, prin exemple simple, modul în care C++ extinde caracteristicile limbajului C și vom pune bazele unei înțelegeri mai profunde a acestuia. Astfel, vom avea un punct de plecare solid pentru paradigma **Orientată Obiect (OO)** pe care o vom studia începând cu laboratorul următor. | + | În cadrul acestui laborator vom evidenția principalele diferențe dintre limbajele C și C++. Vom analiza, prin exemple simple, modul în care C++ extinde caracteristicile limbajului C și vom pune bazele unei înțelegeri mai profunde a acestuia. Astfel, vom avea un punct de plecare solid pentru paradigma **Orientată Obiect (OO)** pe care o vom studia începând cu laboratorul următor. Pentru a înțelege diferențele dintre cele două limbaje mai întâi ar trebui să știm care sunt asemănările, iar pentru asta recomandăm citirea [[poo-is-ab:laboratoare:01| laboratorului 1]]. |
==== Diferențe C/C++ ==== | ==== Diferențe C/C++ ==== | ||
Line 27: | Line 27: | ||
int main() | int main() | ||
{ | { | ||
- | int x; | + | int x; |
- | printf("Introduceti un numar: "); | + | printf("Introduceti un numar: "); |
- | scanf("%d", &x); | + | scanf("%d", &x); |
- | printf("Numarul introdus de utilizator este: %d\n", x); | + | printf("Numarul introdus de utilizator este: %d\n", x); |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 45: | Line 45: | ||
int main() | int main() | ||
{ | { | ||
- | int x; | + | int x; |
- | std::cout << "Introduceti un numar: "; // cout vine de la console output | + | std::cout << "Introduceti un numar: "; // cout vine de la console output |
- | std::cin >> x; // cin vine de la console input | + | std::cin >> x; // cin vine de la console input |
- | std::cout << "Numarul introdus de utilizator este: " << x << '\n'; | + | std::cout << "Numarul introdus de utilizator este: " << x << '\n'; |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 70: | Line 70: | ||
void scrieInFisier(const char* numeFisier) | void scrieInFisier(const char* numeFisier) | ||
{ | { | ||
- | std::ofstream outFile(numeFisier); | + | std::ofstream outFile(numeFisier); |
- | if (!outFile) | + | if (!outFile) // verificam daca fisierul a fost deschis |
- | { | + | { |
- | std::cerr << "Eroare la deschiderea fisierului pentru scriere!\n"; | + | std::cerr << "Eroare la deschiderea fisierului pentru scriere!\n"; |
- | return; | + | return; |
- | } | + | } |
- | outFile << "Ana" << " " << 20 << " " << 9.5 << '\n'; | + | outFile << "Ana" << " " << 20 << " " << 9.5 << '\n'; |
- | outFile << "Ion" << " " << 22 << " " << 8.75 << '\n'; | + | outFile << "Ion" << " " << 22 << " " << 8.75 << '\n'; |
- | outFile << "Maria" << " " << 19 << " " << 10.0 << '\n'; | + | outFile << "Maria" << " " << 19 << " " << 10.0 << '\n'; |
- | outFile.close(); | + | outFile.close(); |
} | } | ||
void citesteDinFisier(const char* numeFisier) | void citesteDinFisier(const char* numeFisier) | ||
{ | { | ||
- | std::ifstream inFile(numeFisier); | + | std::ifstream inFile(numeFisier); |
- | if (!inFile) | + | if (!inFile) // verificam daca fisierul a fost deschis |
- | { | + | { |
- | std::cerr << "Eroare la deschiderea fisierului pentru citire!\n"; | + | std::cerr << "Eroare la deschiderea fisierului pentru citire!\n"; |
- | return; | + | return; |
- | } | + | } |
- | int varsta; | + | int varsta; |
- | double nota; | + | double nota; |
- | char nume[50]; | + | char nume[50]; |
- | std::cout << "Inregistrari citite din fisier\n\n"; | + | std::cout << "Inregistrarile citite din fisier se pot observa mai jos\n\n"; |
- | while (inFile >> nume >> varsta >> nota) // citim pana cand nu mai avem date | + | while (inFile >> nume >> varsta >> nota) // citim pana cand nu mai avem date |
- | { | + | { |
- | std::cout << "Nume: " << nume | + | std::cout << "Nume: " << nume |
- | << ", Varsta: " << varsta | + | << ", Varsta: " << varsta |
- | << ", Nota: " << nota << '\n'; | + | << ", Nota: " << nota << '\n'; |
- | } | + | } |
- | inFile.close(); | + | inFile.close(); |
} | } | ||
int main() | int main() | ||
{ | { | ||
- | const char* denumireFisier = "studenti.txt"; | + | const char* denumireFisier = "studenti.txt"; |
- | scrieInFisier(denumireFisier); | + | scrieInFisier(denumireFisier); |
- | citesteDinFisier(denumireFisier); | + | citesteDinFisier(denumireFisier); |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
- | <note>În mod normal nu este necesară apelarea funcției **close** pentru a închide fluxurile de citire și de scriere în fișier, deoarece acestea au un mecanism automat de închidere atunci când se termină execuția unei funcții. În cazul exemplului nostru nu este necesară apelarea funcției **close** deoarece variabilele de tip **ifstream** și **ofstream** sunt variabile locale în funcțiile în care apar. Dacă am fi scris tot codul în funcția **main** atunci apelarea funcției **close** devenea obligatorie după ce terminam partea de scriere în fișier pentru a putea deschide același fișier în modul de citire.</note> | + | Iar în consolă output-ul arată ca mai jos. |
+ | |||
+ | <file> | ||
+ | Inregistrarile citite din fisier se pot observa mai jos | ||
+ | |||
+ | Nume: Ana, Varsta: 20, Nota: 9.5 | ||
+ | Nume: Ion, Varsta: 22, Nota: 8.75 | ||
+ | Nume: Maria, Varsta: 19, Nota: 10 | ||
+ | </file> | ||
+ | |||
+ | <note tip>În mod normal nu este necesară apelarea funcției **close** pentru a închide fluxurile de **citire** și de **scriere** în fișier, deoarece acestea au un **mecanism automat** de închidere atunci când se termină execuția unei funcții. În cazul exemplului de mai sus nu este necesară apelarea funcției **close** deoarece variabilele de tip **ifstream** și **ofstream** sunt variabile locale în funcțiile în care apar. Dacă am fi scris tot codul în funcția **main** atunci apelarea funcției **close** devenea obligatorie după ce terminam partea de scriere în fișier.</note> | ||
=== Alocarea dinamică a memoriei === | === Alocarea dinamică a memoriei === | ||
Line 137: | Line 147: | ||
int main() | int main() | ||
{ | { | ||
- | int* ptr1 = (int*)malloc(sizeof(int)); | + | int* ptr1 = (int*)malloc(sizeof(int)); |
- | *ptr1 = 5; | + | *ptr1 = 5; |
- | // sau folosind calloc | + | // sau folosind calloc |
- | int* ptr2 = (int*)calloc(1, sizeof(int)); | + | int* ptr2 = (int*)calloc(1, sizeof(int)); |
- | std::cout << *ptr2 << '\n'; | + | std::cout << *ptr2 << '\n'; |
- | *ptr2 = *ptr1; | + | *ptr2 = *ptr1; |
- | std::cout << *ptr1 << '\n'; | + | std::cout << *ptr1 << '\n'; |
- | std::cout << *ptr2 << '\n'; | + | std::cout << *ptr2 << '\n'; |
- | free(ptr1); | + | free(ptr1); |
- | free(ptr2); | + | free(ptr2); |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 161: | Line 171: | ||
<code cpp> | <code cpp> | ||
+ | #include <iostream> | ||
+ | |||
int main() | int main() | ||
{ | { | ||
- | int nrElemente = 5; | + | int nrElemente = 5; |
- | int* vector = (int*)malloc(nrElemente * sizeof(int)); | + | int* vector = (int*)malloc(nrElemente * sizeof(int)); |
- | vector[0] = 3; | + | vector[0] = 3; |
- | vector[1] = 2; | + | vector[1] = 2; |
- | vector[2] = -2; | + | vector[2] = -2; |
- | vector[3] = 10; | + | vector[3] = 10; |
- | vector[4] = 8; | + | vector[4] = 8; |
- | std::cout << "Vectorul alocat dinamic este: "; | + | std::cout << "Vectorul alocat dinamic este: "; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << vector[i] << ' '; | + | std::cout << vector[i] << ' '; |
- | } | + | } |
- | free(vector); | + | free(vector); |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 188: | Line 200: | ||
<code cpp> | <code cpp> | ||
+ | #include <iostream> | ||
+ | |||
int main() | int main() | ||
{ | { | ||
- | int nrElemente = 5; | + | int nrElemente = 5; |
- | int* vector = (int*)malloc(nrElemente * sizeof(int)); | + | int* vector = (int*)malloc(nrElemente * sizeof(int)); |
- | vector[0] = 3; | + | vector[0] = 3; |
- | vector[1] = 2; | + | vector[1] = 2; |
- | vector[2] = -2; | + | vector[2] = -2; |
- | vector[3] = 10; | + | vector[3] = 10; |
- | vector[4] = 8; | + | vector[4] = 8; |
- | std::cout << "Vectorul alocat dinamic este: "; | + | std::cout << "Vectorul alocat dinamic este: "; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << vector[i] << ' '; | + | std::cout << vector[i] << ' '; |
- | } | + | } |
- | nrElemente = 8; | + | nrElemente = 8; |
- | vector = (int*)realloc(vector, nrElemente * sizeof(int)); | + | vector = (int*)realloc(vector, nrElemente * sizeof(int)); |
- | vector[5] = 15; | + | vector[5] = 15; |
- | vector[6] = 20; | + | vector[6] = 20; |
- | vector[7] = 25; | + | vector[7] = 25; |
- | std::cout << "\nVectorul realocat dinamic este: "; | + | std::cout << "\nVectorul realocat dinamic este: "; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << vector[i] << ' '; | + | std::cout << vector[i] << ' '; |
- | } | + | } |
- | free(vector); | + | free(vector); |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 240: | Line 254: | ||
int main() | int main() | ||
{ | { | ||
- | int* ptr1 = new int; // alocare dinamica fara initializare, compilatorul va atribui o valoare in mod aleator | + | int* ptr1 = new int; // alocare dinamica fara initializare, compilatorul va atribui o valoare in mod aleator |
- | int* ptr2 = new int(10); // alocare dinamica cu initializare | + | int* ptr2 = new int(10); // alocare dinamica cu initializare |
- | std::cout << *ptr1 << '\n'; | + | std::cout << *ptr1 << '\n'; |
- | std::cout << *ptr2 << '\n'; | + | std::cout << *ptr2 << '\n'; |
- | /*delete ptr1, ptr2; // desi nu da eroare de compilare va elibera doar spatiul pentru ptr1, nu se recomanda aceasta scriere pentru ca va genera memory leak-uri usor*/ | + | /*delete ptr1, ptr2; // desi nu da eroare de compilare va elibera doar spatiul pentru ptr1, nu se recomanda aceasta scriere pentru ca va genera memory leak-uri usor*/ |
- | delete ptr1; | + | delete ptr1; |
- | delete ptr2; | + | delete ptr2; |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 266: | Line 280: | ||
int main() | int main() | ||
{ | { | ||
- | int nrElemente = 5; | + | int nrElemente = 5; |
- | int* vector = new int[nrElemente]; // se folosesc [] pentru a anunta compilatorul ca vrem sa alocam spatiu pentru un bloc de memorie continuu | + | int* vector = new int[nrElemente]; // se folosesc [] pentru a anunta compilatorul ca vrem sa alocam spatiu pentru un bloc de memorie continuu |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << "vector[" << i << "] = "; | + | std::cout << "vector[" << i << "] = "; |
- | std::cin >> vector[i]; | + | std::cin >> vector[i]; |
- | } | + | } |
- | std::cout << "\nElementele vectorului alocat sunt: "; | + | std::cout << "\nElementele vectorului alocat sunt: "; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << vector[i] << ' '; | + | std::cout << vector[i] << ' '; |
- | } | + | } |
- | delete[] vector; // se folosesc [] pentru a anunta compilatorul ca ne dorim sa eliberam memoria unui bloc contiguu | + | delete[] vector; // se folosesc [] pentru a anunta compilatorul ca ne dorim sa eliberam memoria unui bloc contiguu |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 295: | Line 309: | ||
int main() | int main() | ||
{ | { | ||
- | int nrElemente = 6; | + | int nrElemente = 6; |
- | int* vector = new int[nrElemente]; | + | int* vector = new int[nrElemente]; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << "vector[" << i << "] = "; | + | std::cout << "vector[" << i << "] = "; |
- | std::cin >> vector[i]; | + | std::cin >> vector[i]; |
- | } | + | } |
- | std::cout << "\nElementele vectorului alocat sunt: "; | + | std::cout << "\nElementele vectorului alocat sunt: "; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << vector[i] << ' '; | + | std::cout << vector[i] << ' '; |
- | } | + | } |
- | delete[] vector; | + | delete[] vector; |
- | nrElemente = 3; | + | nrElemente = 3; |
- | vector = new int[nrElemente]; | + | vector = new int[nrElemente]; |
- | std::cout << "\n\n===================================================\n\n"; | + | std::cout << "\n\n===================================================\n\n"; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << "vector[" << i << "] = "; | + | std::cout << "vector[" << i << "] = "; |
- | std::cin >> vector[i]; | + | std::cin >> vector[i]; |
- | } | + | } |
- | std::cout << "\nElementele vectorului realocat sunt: "; | + | std::cout << "\nElementele vectorului realocat sunt: "; |
- | for (int i = 0; i < nrElemente; i++) | + | for (int i = 0; i < nrElemente; i++) |
- | { | + | { |
- | std::cout << vector[i] << ' '; | + | std::cout << vector[i] << ' '; |
- | } | + | } |
- | std::cout << '\n'; | + | std::cout << '\n'; |
- | delete[] vector; | + | delete[] vector; |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 356: | Line 370: | ||
int main() | int main() | ||
{ | { | ||
- | int x = 10; | + | int x = 10; |
- | int& ref = x; | + | int& ref = x; |
- | ref = 16; | + | ref = 16; |
- | std::cout << x << '\n'; // x devine 16 deoarece ref este un alias pentru el | + | std::cout << x << '\n'; // x devine 16 deoarece ref este un alias pentru el |
- | x = 20; | + | x = 20; |
- | std::cout << ref << '\n'; // ref este 20 datorita faptului ca se refera la x | + | std::cout << ref << '\n'; // ref este 20 datorita faptului ca se refera la x |
- | int y = 0; | + | int y = 0; |
- | ref = y; // poate parea schimbarea referintei dar in realitate este doar atribuirea valorii 0 lui ref | + | ref = y; // poate parea schimbarea referintei dar in realitate este doar atribuirea valorii 0 lui ref |
- | std::cout << x << '\n'; // x este 0 din motive evidente | + | std::cout << x << '\n'; // x este 0 din motive evidente |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 387: | Line 401: | ||
void alocareVector(int*& v, const int& dim) | void alocareVector(int*& v, const int& dim) | ||
{ | { | ||
- | v = new int[dim]; | + | v = new int[dim]; |
} | } | ||
void citireVector(int*& v, const int& dim) | void citireVector(int*& v, const int& dim) | ||
{ | { | ||
- | for (int i = 0; i < dim; i++) | + | for (int i = 0; i < dim; i++) |
- | { | + | { |
- | std::cout << "vector[" << i << "] = "; | + | std::cout << "vector[" << i << "] = "; |
- | std::cin >> v[i]; | + | std::cin >> v[i]; |
- | } | + | } |
} | } | ||
void afisareVector(const int* const& v, const int& dim) | void afisareVector(const int* const& v, const int& dim) | ||
{ | { | ||
- | std::cout << "Elementele vectorului alocat sunt: "; | + | std::cout << "Elementele vectorului alocat sunt: "; |
- | for (int i = 0; i < dim; i++) | + | for (int i = 0; i < dim; i++) |
- | { | + | { |
- | std::cout << v[i] << ' '; | + | std::cout << v[i] << ' '; |
- | } | + | } |
- | std::cout << '\n'; | + | std::cout << '\n'; |
} | } | ||
void dezalocareVector(int*& v) | void dezalocareVector(int*& v) | ||
{ | { | ||
- | if (v != nullptr) | + | if (v != nullptr) |
- | { | + | { |
- | delete[] v; | + | delete[] v; |
- | } | + | } |
} | } | ||
int main() | int main() | ||
{ | { | ||
- | int nrElemente = 5; | + | int nrElemente = 5; |
- | int* vector = nullptr; | + | int* vector = nullptr; |
- | alocareVector(vector, nrElemente); | + | alocareVector(vector, nrElemente); |
- | citireVector(vector, nrElemente); | + | citireVector(vector, nrElemente); |
- | afisareVector(vector, nrElemente); | + | afisareVector(vector, nrElemente); |
- | dezalocareVector(vector); | + | dezalocareVector(vector); |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 446: | Line 460: | ||
int main() | int main() | ||
{ | { | ||
- | int x = NULL; // valid | + | int x = NULL; // valid |
- | int* ptr = NULL; // valid | + | int* ptr = NULL; // valid |
- | ptr = nullptr; // valid | + | ptr = nullptr; // valid |
- | x = nullptr; // eroare de compilare x nu este un pointer | + | x = nullptr; // eroare de compilare, x nu este un pointer |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 467: | Line 481: | ||
int suma(int a, int b) | int suma(int a, int b) | ||
{ | { | ||
- | return a + b; | + | return a + b; |
} | } | ||
float suma(float a, float b) | float suma(float a, float b) | ||
{ | { | ||
- | return a + b; | + | return a + b; |
} | } | ||
float suma(float a, int b) | float suma(float a, int b) | ||
{ | { | ||
- | return a + b; | + | return a + b; |
} | } | ||
float suma(int a, float b) | float suma(int a, float b) | ||
{ | { | ||
- | return a + b; | + | return a + b; |
} | } | ||
int main() | int main() | ||
{ | { | ||
- | std::cout << suma(2, 5) << '\n'; // prima functie denumita suma | + | std::cout << suma(2, 5) << '\n'; // prima functie denumita suma |
- | std::cout << suma(2.5f, 5.5f) << '\n'; // a doua functie denumita suma | + | std::cout << suma(2.5f, 5.5f) << '\n'; // a doua functie denumita suma |
- | std::cout << suma(2.85f, 8) << '\n'; // a treia functie denumita suma | + | std::cout << suma(2.85f, 8) << '\n'; // a treia functie denumita suma |
- | std::cout << suma(10, 8.5f) << '\n'; // // a patra functie denumita suma | + | std::cout << suma(10, 8.5f) << '\n'; // // a patra functie denumita suma |
- | return 0; | + | return 0; |
} | } | ||
</code> | </code> | ||
Line 499: | Line 513: | ||
==== Concluzii ==== | ==== Concluzii ==== | ||
- | Prin parcurgerea acestui laborator, putem spune cu certitudine că limbajul C++ reprezintă o evoluție firească a limbajului C, adăugând numeroase concepte și mecanisme care ne fac munca de programatori mai simplă și mai expresivă. Am văzut că librăria **fstream**, alocarea dinamică realizată într-un mod simplificat, introducerea referințelor, posibilitatea de a supraîncărca funcții și suportul pentru **Programarea Orientată Obiect** diferențiază C++ de C și ne oferă un cadru mai flexibil pentru dezvoltarea aplicațiilor. Totuși, este important să reținem că C++ rămâne compatibil cu C la nivel de bază, ceea ce îl face un limbaj versatil, potrivit atât pentru stilul **procedural**, cât și pentru cel **orientat pe obiecte**. | + | Prin parcurgerea acestui laborator, putem spune cu certitudine că limbajul C++ reprezintă o evoluție firească a limbajului C, adăugând numeroase concepte și mecanisme care ne fac munca de programatori mai simplă și mai expresivă. Am văzut că librăria **fstream**, alocarea dinamică realizată într-un mod simplificat, introducerea referințelor, posibilitatea de a supraîncărca funcții și suportul pentru **Programarea Orientată Obiect** diferențiază C++ de C și ne oferă un cadru mai flexibil pentru dezvoltarea aplicațiilor. Totuși, este important să reținem faptul că C++ rămâne compatibil cu C la nivel de bază, ceea ce îl face un limbaj versatil, potrivit atât pentru stilul **procedural**, cât și pentru cel **orientat pe obiecte**. |