🗂️ Structuri (struct)

Capitolul 10 — Tipuri compuse de date: declarare, câmpuri, vectori, sortare, BAC

structdate compusesortareBACtipuri utilizator
📖 12 min
0
🗂️

Declarare struct

💡 Ce este un 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
Atenție: Definiția struct-ului se pune global (înainte de orice funcție), nu înăuntrul lui main(). Altfel nu este vizibil în alte funcții.
Struct tipice la BAC:
  • 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
Operator punct .

Folosit cu variabile struct obișnuite: p.pret, s.medie

Operator săgeată ->

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;
}
Parcurgerea unui vector de struct-uri se face exact ca la un vector obișnuit — cu 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;
});
La BAC apare frecvent: „sortează elevii descrescător după medie; la egalitate, crescător după nume"
// 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)
}
Prin valoare

Funcția primește copie. Modificările nu afectează originalul. Potrivit pentru funcții care doar citesc.

Prin referință (&)

Funcția modifică originalul. Potrivit pentru funcții de citire, sortare, modificare.

🎓

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;
}
Pași problemă struct la BAC

1. Declară struct global
2. Citește tablou de struct
3. Parcurge și filtrează
4. Sortează dacă e cerut
5. Afișează rezultate

Greșeli frecvente

- Struct definit în main (nu e global)
- Uitat ; după } struct
- Sortat după câmpul greșit
- Compararea float cu ==