Declarare struct
Un struct este un tip de dată definit de programator care grupează mai multe câmpuri de tipuri diferite sub un singur nume. Este util când vrem să reprezentăm o entitate (persoană, produs, student) cu mai multe atribute.
// Sintaxa generală struct NumeTip { tip1 camp1; tip2 camp2; // ... }; // <-- punct-virgulă obligatoriu! // Exemplu: struct pentru un student struct Student { char nume[50]; int varsta; float medie; }; // Declarare variabile de tip Student Student s1, s2; Student clasa[30]; // tablou de 30 de studenți
main(). Altfel nu este vizibil în alte funcții.
- Persoana: nume + vârstă + salariu
- Student: nume + medie + grup
- Produs: cod + denumire + preț + stoc
- Punct: x + y (coordonate 2D)
Câmpuri și acces
Câmpurile se accesează cu operatorul punct . (pentru variabile obișnuite) sau cu operatorul săgeată -> (pentru pointeri la struct).
struct Produs { char denumire[50]; float pret; int stoc; }; Produs p; // Citire câmpuri cin >> p.denumire >> p.pret >> p.stoc; // Afișare câmpuri cout << p.denumire << " " << p.pret << " " << p.stoc << endl; // Modificare câmp p.stoc -= 1; // vânzare 1 produs p.pret *= 1.1; // scumpire 10% // Atribuire struct (copie completă a tuturor câmpurilor) Produs p2 = p; // p2 este o copie independentă a lui p
. Folosit cu variabile struct obișnuite: p.pret, s.medie
-> Folosit cu pointeri la struct: ptr->pret echivalent cu (*ptr).pret
Vector de structuri
Cel mai frecvent mod de utilizare la BAC: un tablou de struct-uri citit din tastatură sau fișier.
struct Elev { char nume[30]; float medie; int clasa; }; Elev v[100]; int n; int main() { cin >> n; // Citire vector de struct-uri for (int i = 0; i < n; i++) cin >> v[i].nume >> v[i].medie >> v[i].clasa; // Afișare for (int i = 0; i < n; i++) cout << v[i].nume << "\t" << v[i].medie << "\t" << v[i].clasa << "\n"; // Găsire elev cu media maximă int idxMax = 0; for (int i = 1; i < n; i++) if (v[i].medie > v[idxMax].medie) idxMax = i; cout << "Cel mai bun elev: " << v[idxMax].nume << endl; }
for (int i = 0; i < n; i++), accesând câmpurile cu v[i].câmp.
Sortare după câmp
Metoda 1: Bubble sort (clasic, O(n²))
// Sortare crescătoare după medie (Bubble Sort) for (int i = 0; i < n-1; i++) for (int j = 0; j < n-i-1; j++) if (v[j].medie > v[j+1].medie) { Elev tmp = v[j]; v[j] = v[j+1]; // interschimb complet (toate câmpurile) v[j+1] = tmp; }
Metoda 2: sort() cu comparator lambda (O(n log n))
// Necesită #include <algorithm> // Sortare crescătoare după medie sort(v, v+n, [](const Elev& a, const Elev& b) { return a.medie < b.medie; }); // Sortare descrescătoare după medie sort(v, v+n, [](const Elev& a, const Elev& b) { return a.medie > b.medie; }); // Sortare alfabetică după nume sort(v, v+n, [](const Elev& a, const Elev& b) { return strcmp(a.nume, b.nume) < 0; });
// Sortare cu criteriu dublu sort(v, v+n, [](const Elev& a, const Elev& b) { if (a.medie != b.medie) return a.medie > b.medie; // descrescător medie return strcmp(a.nume, b.nume) < 0; // crescător alfab. });
Structuri în funcții
struct Punct { double x, y; }; // Transmitere prin valoare (funcția primește o COPIE) double distanta(Punct a, Punct b) { double dx = a.x - b.x, dy = a.y - b.y; return sqrt(dx*dx + dy*dy); // #include <cmath> } // Transmitere prin referință (funcția modifică originalul) void translateaza(Punct& p, double dx, double dy) { p.x += dx; // modifică originalul! p.y += dy; } // Funcție care returnează un struct Punct mijloc(Punct a, Punct b) { Punct m; m.x = (a.x + b.x) / 2; m.y = (a.y + b.y) / 2; return m; } int main() { Punct p1 = {0, 0}, p2 = {3, 4}; // inițializare cu liste cout << distanta(p1, p2) << endl; // 5.0 translateaza(p1, 1, 1); // p1 devine (1,1) Punct m = mijloc(p1, p2); // m = (2, 2.5) }
Funcția primește copie. Modificările nu afectează originalul. Potrivit pentru funcții care doar citesc.
Funcția modifică originalul. Potrivit pentru funcții de citire, sortare, modificare.
Demo interactiv — Struct în acțiune
Vizualizează cum arată un struct în memorie — fiecare câmp cu numele, tipul și valoarea lui. Sortează după orice câmp!
5 probleme clasice cu structuri — elev, punct, carte, produs.
3 Ana 9.20 Bogdan 8.50 Carmen 9.75
Carmen
💡 Vezi soluția
struct Elev { string nume; double medie; }; int n; cin >> n; Elev e[105], best; best.medie = -1; for (int i = 0; i < n; i++) { cin >> e[i].nume >> e[i].medie; if (e[i].medie > best.medie) best = e[i]; } cout << best.nume;
Punct { double x, y; }. Citește două puncte și afișează distanța euclidiană (2 zecimale).0 0 3 4
5.00
💡 Vezi soluția
struct Punct { double x, y; }; Punct a, b; cin >> a.x >> a.y >> b.x >> b.y; double d = sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); cout << fixed << setprecision(2) << d;
3 Baltagul Sadoveanu 1930 Maitreyi Eliade 1933 Ion Rebreanu 1920
Ion Baltagul Maitreyi
💡 Vezi soluția
struct Carte { string titlu, autor; int an; }; Carte c[105]; int n; cin >> n; for (int i = 0; i < n; i++) cin >> c[i].titlu >> c[i].autor >> c[i].an; sort(c, c+n, [](Carte a, Carte b){ return a.an < b.an; }); for (int i = 0; i < n; i++) cout << c[i].titlu << '\n';
Idee: sort cu comparator lambda. La BAC poate apărea și ca bool cmp(Carte a, Carte b) { return a.an < b.an; }.
Produs { string nume; double pret; int procReducere; }. Scrie funcția double pretFinal(Produs p). Afișează prețul final pentru fiecare din n produse citite.2 Tricou 100 20 Pantaloni 200 10
Tricou 80.00 Pantaloni 180.00
💡 Vezi soluția
struct Produs { string nume; double pret; int procReducere; }; double pretFinal(Produs p) { return p.pret * (100 - p.procReducere) / 100.0; } int n; cin >> n; for (int i = 0; i < n; i++) { Produs p; cin >> p.nume >> p.pret >> p.procReducere; cout << p.nume << ' ' << fixed << setprecision(2) << pretFinal(p) << '\n'; }
5 Ana 9.2 Bogdan 8.5 Carmen 9.75 Dan 7.8 Eva 9.5
Carmen 9.75 Eva 9.50 Ana 9.20
💡 Vezi soluția
struct Elev { string nume; double medie; }; int n; cin >> n; Elev e[105]; for (int i = 0; i < n; i++) cin >> e[i].nume >> e[i].medie; sort(e, e+n, [](Elev a, Elev b){ return a.medie > b.medie; }); int k = min(3, n); for (int i = 0; i < k; i++) cout << e[i].nume << ' ' << fixed << setprecision(2) << e[i].medie << '\n';
Trucuri: 1) return a.medie > b.medie pentru descrescător; 2) min(3, n) evită out-of-bounds dacă sunt mai puțini elevi.
Probleme tip BAC — struct
Problema 1: Elevii cu media peste 9
struct Elev { char nume[30]; float medie; }; Elev v[100]; int n; int main() { cin >> n; for (int i = 0; i < n; i++) cin >> v[i].nume >> v[i].medie; // a) Afișare elevi cu medie > 9 for (int i = 0; i < n; i++) if (v[i].medie > 9) cout << v[i].nume << endl; // b) Sortare descrescătoare după medie sort(v, v+n, [](const Elev& a, const Elev& b) { return a.medie > b.medie; }); // c) Afișare clasament for (int i = 0; i < n; i++) cout << i+1 << ". " << v[i].nume << " - " << v[i].medie << "\n"; }
Problema 2: Inventar produse — prețul mediu și produsele sub medie
struct Produs { char cod[10]; float pret; int stoc; }; Produs p[500]; int n; int main() { cin >> n; float suma = 0; for (int i = 0; i < n; i++) { cin >> p[i].cod >> p[i].pret >> p[i].stoc; suma += p[i].pret; } float mediu = suma / n; cout << "Pret mediu: " << mediu << endl; // Produse sub prețul mediu cout << "Sub medie:" << endl; for (int i = 0; i < n; i++) if (p[i].pret < mediu) cout << p[i].cod << ": " << p[i].pret << endl; }
1. Declară struct global
2. Citește tablou de struct
3. Parcurge și filtrează
4. Sortează dacă e cerut
5. Afișează rezultate
- Struct definit în main (nu e global)
- Uitat ; după } struct
- Sortat după câmpul greșit
- Compararea float cu ==