Structuri de Date Neomogene (STRUCT): Cum Faci Cutii Cu Compartimente Speciale – Materie BAC

Bun, hai să vorbim despre unul dintre cele mai utile concepte din programare: STRUCTURILE (struct). Nu e doar despre gruparea datelor (cuvânt abstract) și organizare. E despre cum poți crea propriile tale tipuri de date personalizate, care să modeleze obiecte din lumea reală. E un proces atât de puternic încât dacă ar fi să reprezinți o persoană fără structuri, ai avea variabile împrăștiate peste tot. Dar aici intervine și partea strategică: cum să grupezi datele în mod inteligent.

1. Ce este o STRUCTURĂ? “Cutia cu Mai Multe Compartimente”

Gândește-te la ea ca la un dosar de catastrofe pentru o persoană: are compartiment pentru nume, pentru vârstă, pentru adresă, pentru note. Toate la un loc, organizat frumos.

Definiția Structurii:
O structură este un tip de date definit de utilizator care grupează variabile de tipuri diferite sub un singur nume.

Analogie cu un Formular:

Când completezi un formular la doctor:

  • Nume: _
  • Vârstă: __
  • Înălțime: __
  • Grupa sanguină: _

Toate câmpurile astea formează împreună DOSARUL tău medical.
În programare, acest dosar este o STRUCTURĂ.

Exemplu fără struct vs cu struct:

// FĂRĂ structură - variabile împrăștiate
string numeStudent1;
int varstaStudent1;
double mediaStudent1;

string numeStudent2;
int varstaStudent2;
double mediaStudent2;
// ... și așa mai departe pentru 30 de studenți - HAOS!

// CU structură - totul organizat
struct Student {
    string nume;
    int varsta;
    double media;
};

Student student1, student2; // Doi studenți organizați

2. Cum se Definește și se Folosește o STRUCTURĂ?

Pasul 1: DEFINIȚIA structurii (Crearea șablonului)

#include <iostream>
#include <string>
using namespace std;

// Definim șablonul structurii (în afara funcțiilor, de obicei)
struct Student {
    // Câmpurile (membrii) structurii
    string nume;
    string prenume;
    int varsta;
    double media;
    int anStudiu;
}; // ATENȚIE la punct și virgulă la sfârșit!

struct DataCalendaristica {
    int zi;
    string luna;
    int an;
};

struct Produs {
    string denumire;
    double pret;
    int cantitateStoc;
    string codBare;
};

Pasul 2: DECLARAREA variabilelor de tip structură

int main() {
    // Declarăm variabile de tipul structurii definite
    Student student1;           // Un student
    Student student2, student3; // Mai mulți studenți

    DataCalendaristica azi;     // O dată calendaristică
    DataCalendaristica examen;  // Altă dată

    Produs laptop;              // Un produs
    Produs telefon, tableta;    // Mai multe produse

    return 0;
}

Pasul 3: ACCESAREA și MODIFICAREA câmpurilor

#include <iostream>
#include <string>
using namespace std;

struct Student {
    string nume;
    string prenume;
    int varsta;
    double media;
};

int main() {
    Student student;

    // ATRIBUIREA valorilor - folosim operatorul punct (.)
    student.nume = "Popescu";
    student.prenume = "Ion";
    student.varsta = 20;
    student.media = 9.25;

    // AFIȘAREA valorilor
    cout << "Nume student: " << student.nume << " " << student.prenume << endl;
    cout << "Varsta: " << student.varsta << " ani" << endl;
    cout << "Media: " << student.media << endl;

    // MODIFICAREA valorilor
    cout << "\nStudentul a luat o notă nouă..." << endl;
    student.media = 9.50;
    cout << "Noua medie: " << student.media << endl;

    // CITIREA de la tastatură
    cout << "\nIntrodu date pentru un nou student:" << endl;
    cout << "Nume: ";
    cin >> student.nume;
    cout << "Prenume: ";
    cin >> student.prenume;
    cout << "Varsta: ";
    cin >> student.varsta;
    cout << "Media: ";
    cin >> student.media;

    cout << "\nStudentul introdus: " << student.nume << " " 
         << student.prenume << ", " << student.varsta << " ani, media " 
         << student.media << endl;

    return 0;
}

3. Inițializarea Structurilor – “Umplerea Dosarului de la Început”

#include <iostream>
#include <string>
using namespace std;

struct Carte {
    string titlu;
    string autor;
    int anPublicatie;
    double pret;
};

int main() {
    // Metoda 1: Inițializare câmp cu câmp
    Carte carte1;
    carte1.titlu = "Ion";
    carte1.autor = "Liviu Rebreanu";
    carte1.anPublicatie = 1920;
    carte1.pret = 29.99;

    // Metoda 2: Inițializare la declarare (C++11 și mai nou)
    Carte carte2 = {"Amintiri din copilarie", "Ion Creanga", 1880, 19.99};

    // Metoda 3: Inițializare cu constructor (mai avansat)
    Carte carte3{"Morometii", "Marin Preda", 1955, 34.50};

    // Metoda 4: Copiere dintr-o altă structură
    Carte carte4 = carte2;  // Copiază toate câmpurile

    cout << "Carte 1: " << carte1.titlu << " de " << carte1.autor << endl;
    cout << "Carte 2: " << carte2.titlu << " de " << carte2.autor << endl;
    cout << "Carte 3: " << carte3.titlu << " de " << carte3.autor << endl;
    cout << "Carte 4 (copie): " << carte4.titlu << " de " << carte4.autor << endl;

    return 0;
}

4. Structuri în Structuri – “Dosare în Dosare”

Poți avea structuri care conțin alte structuri!

#include <iostream>
#include <string>
using namespace std;

struct Adresa {
    string strada;
    string oras;
    string codPostal;
};

struct Persoana {
    string nume;
    string prenume;
    int varsta;
    Adresa domiciliu;  // Structură în structură!
    double salariu;
};

int main() {
    Persoana angajat;

    // Completăm datele
    angajat.nume = "Ionescu";
    angajat.prenume = "Maria";
    angajat.varsta = 32;
    angajat.salariu = 5500.50;

    // Completăm adresa (care e o structură în interior)
    angajat.domiciliu.strada = "Str. Libertății nr. 15";
    angajat.domiciliu.oras = "București";
    angajat.domiciliu.codPostal = "010101";

    // Afișăm
    cout << "Angajat: " << angajat.nume << " " << angajat.prenume << endl;
    cout << "Varsta: " << angajat.varsta << " ani" << endl;
    cout << "Salariu: " << angajat.salariu << " RON" << endl;
    cout << "Adresa: " << angajat.domiciliu.strada << ", " 
         << angajat.domiciliu.oras << ", " 
         << angajat.domiciliu.codPostal << endl;

    return 0;
}

5. Vectori de Structuri – “Cutii întregi de Dosare”

Aici devine interesant: poți avea tablouri (vectori) de structuri!

#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

struct Student {
    string nume;
    string prenume;
    double media;
};

int main() {
    const int NUMAR_STUDENTI = 3;
    Student grupa[NUMAR_STUDENTI];  // Vector de structuri

    // Citirea datelor pentru toți studenții
    cout << "Introdu datele pentru " << NUMAR_STUDENTI << " studenti:\n";
    for(int i = 0; i < NUMAR_STUDENTI; i++) {
        cout << "\n--- Studentul " << i+1 << " ---\n";
        cout << "Nume: ";
        cin >> grupa[i].nume;
        cout << "Prenume: ";
        cin >> grupa[i].prenume;
        cout << "Media: ";
        cin >> grupa[i].media;
    }

    // Afișarea tuturor studenților
    cout << "\n\n=== LISTA STUDENTILOR ===\n";
    cout << setw(20) << left << "Nume Prenume" 
         << setw(10) << right << "Media" << endl;
    cout << string(30, '-') << endl;

    for(int i = 0; i < NUMAR_STUDENTI; i++) {
        cout << setw(20) << left << (grupa[i].nume + " " + grupa[i].prenume)
             << setw(10) << right << fixed << setprecision(2) << grupa[i].media 
             << endl;
    }

    // Calculul mediei generale a grupei
    double sumaMedii = 0;
    for(int i = 0; i < NUMAR_STUDENTI; i++) {
        sumaMedii += grupa[i].media;
    }
    double mediaGenerala = sumaMedii / NUMAR_STUDENTI;

    cout << "\nMedia generala a grupei: " << fixed << setprecision(2) 
         << mediaGenerala << endl;

    return 0;
}

6. Structuri cu Vectori în Interior – “Dosare cu Liste”

Structurile pot conține și vectori!

#include <iostream>
#include <string>
using namespace std;

struct Elev {
    string nume;
    string prenume;
    int note[5];  // Vector în structură - 5 note
    double media;
};

int main() {
    Elev elev;

    // Completăm datele elevului
    elev.nume = "Vasilescu";
    elev.prenume = "Andrei";

    cout << "Introdu cele 5 note pentru " << elev.nume << " " 
         << elev.prenume << ":\n";

    // Citim notele
    int suma = 0;
    for(int i = 0; i < 5; i++) {
        cout << "Nota " << i+1 << ": ";
        cin >> elev.note[i];
        suma += elev.note[i];
    }

    // Calculăm media
    elev.media = suma / 5.0;

    // Afișăm rezultatele
    cout << "\n--- Rezultatele elevului ---\n";
    cout << "Nume: " << elev.nume << " " << elev.prenume << endl;
    cout << "Note: ";
    for(int i = 0; i < 5; i++) {
        cout << elev.note[i] << " ";
    }
    cout << "\nMedia: " << elev.media << endl;

    // Verificăm dacă este corigent
    if(elev.media >= 5.0) {
        cout << "STATUS: Promovat!" << endl;
    } else {
        cout << "STATUS: Corigent!" << endl;
    }

    return 0;
}

7. Compararea și Căutarea în Structuri

#include <iostream>
#include <string>
using namespace std;

struct Produs {
    string nume;
    double pret;
    int cantitate;
};

int main() {
    Produs magazin[4] = {
        {"Laptop", 3500.00, 10},
        {"Telefon", 1500.00, 25},
        {"Tableta", 1200.00, 15},
        {"Ceas", 500.00, 30}
    };

    // Căutare produs după nume
    string cautaProdus;
    cout << "Ce produs cauti? ";
    cin >> cautaProdus;

    bool gasit = false;
    for(int i = 0; i < 4; i++) {
        if(magazin[i].nume == cautaProdus) {
            cout << "Produs gasit!\n";
            cout << "Pret: " << magazin[i].pret << " RON\n";
            cout << "Cantitate in stoc: " << magazin[i].cantitate << endl;
            gasit = true;
            break;
        }
    }

    if(!gasit) {
        cout << "Produsul nu a fost gasit in magazin.\n";
    }

    // Găsirea celui mai scump produs
    Produs celMaiScump = magazin[0];
    for(int i = 1; i < 4; i++) {
        if(magazin[i].pret > celMaiScump.pret) {
            celMaiScump = magazin[i];
        }
    }

    cout << "\nCel mai scump produs este: " << celMaiScump.nume 
         << " cu pretul de " << celMaiScump.pret << " RON\n";

    return 0;
}

8. Structuri ca Parametri ai Funcțiilor – “Trimitem Dosarele”

#include <iostream>
#include <string>
using namespace std;

struct Angajat {
    string nume;
    string functie;
    double salariu;
    int vechime;
};

// Funcție care primește o structură ca parametru
void afiseazaAngajat(Angajat a) {
    cout << "\n--- Detalii angajat ---\n";
    cout << "Nume: " << a.nume << endl;
    cout << "Functie: " << a.functie << endl;
    cout << "Salariu: " << a.salariu << " RON" << endl;
    cout << "Vechime: " << a.vechime << " ani" << endl;
}

// Funcție care modifică o structură (prin referință)
void maresteSalariu(Angajat &a, double procent) {
    double marire = a.salariu * (procent / 100);
    a.salariu += marire;
    cout << "Salariul a fost marit cu " << procent << "% (" 
         << marire << " RON)\n";
}

// Funcție care returnează o structură
Angajat citesteAngajat() {
    Angajat temp;
    cout << "\nIntrodu datele noului angajat:\n";
    cout << "Nume: ";
    cin >> temp.nume;
    cout << "Functie: ";
    cin >> temp.functie;
    cout << "Salariu: ";
    cin >> temp.salariu;
    cout << "Vechime: ";
    cin >> temp.vechime;

    return temp;
}

int main() {
    // Folosim funcțiile cu structuri
    Angajat angajat1 = {"Popescu", "Programator", 7000.00, 3};

    afiseazaAngajat(angajat1);

    // Mărim salariul cu 10%
    maresteSalariu(angajat1, 10);
    afiseazaAngajat(angajat1);

    // Citim un nou angajat
    Angajat angajat2 = citesteAngajat();
    afiseazaAngajat(angajat2);

    return 0;
}

9. PROIECT INTEGRAT: Sistem de Gestionare a Bibliotecii

#include <iostream>
#include <string>
#include <iomanip>
using namespace std;

struct Carte {
    string titlu;
    string autor;
    int anPublicatie;
    string ISBN;  // Codul unic al cărții
    bool esteImprumutata;
};

struct Biblioteca {
    Carte carti[100];  // Maxim 100 de cărți
    int numarCarti;    // Câte cărți avem de fapt
};

void afiseazaMeniu() {
    cout << "\n=== SISTEM GESTIUNE BIBLIOTECA ===\n";
    cout << "1. Adauga carte\n";
    cout << "2. Afiseaza toate cartile\n";
    cout << "3. Cauta carte dupa titlu\n";
    cout << "4. Imprumuta carte\n";
    cout << "5. Returneaza carte\n";
    cout << "6. Carti disponibile (neimprumutate)\n";
    cout << "0. Iesire\n";
    cout << "Alege optiunea: ";
}

void adaugaCarte(Biblioteca &b) {
    if(b.numarCarti >= 100) {
        cout << "Biblioteca este plina!\n";
        return;
    }

    cout << "\n--- Adauga carte noua ---\n";
    cout << "Titlu: ";
    cin.ignore();
    getline(cin, b.carti[b.numarCarti].titlu);

    cout << "Autor: ";
    getline(cin, b.carti[b.numarCarti].autor);

    cout << "An publicatie: ";
    cin >> b.carti[b.numarCarti].anPublicatie;

    cout << "ISBN: ";
    cin >> b.carti[b.numarCarti].ISBN;

    b.carti[b.numarCarti].esteImprumutata = false;
    b.numarCarti++;

    cout << "Carte adaugata cu succes!\n";
}

void afiseazaCarti(Biblioteca &b) {
    if(b.numarCarti == 0) {
        cout << "Biblioteca este goala!\n";
        return;
    }

    cout << "\n=== LISTA CARTI ===\n";
    cout << setw(25) << left << "Titlu" 
         << setw(20) << left << "Autor"
         << setw(10) << left << "An"
         << setw(15) << left << "ISBN"
         << setw(15) << left << "Status" << endl;
    cout << string(85, '-') << endl;

    for(int i = 0; i < b.numarCarti; i++) {
        cout << setw(25) << left << b.carti[i].titlu
             << setw(20) << left << b.carti[i].autor
             << setw(10) << left << b.carti[i].anPublicatie
             << setw(15) << left << b.carti[i].ISBN
             << setw(15) << left << (b.carti[i].esteImprumutata ? "IMPRUMUTATA" : "DISPONIBIL")
             << endl;
    }
}

int main() {
    Biblioteca biblioteca;
    biblioteca.numarCarti = 0;

    int optiune;

    do {
        afiseazaMeniu();
        cin >> optiune;

        switch(optiune) {
            case 1:
                adaugaCarte(biblioteca);
                break;
            case 2:
                afiseazaCarti(biblioteca);
                break;
            case 3:
                // Implementează tu căutarea!
                cout << "Implementare pentru tema ;)\n";
                break;
            case 4:
                // Implementează tu împrumutul!
                cout << "Implementare pentru tema ;)\n";
                break;
            case 5:
                // Implementează tu returnarea!
                cout << "Implementare pentru tema ;)\n";
                break;
            case 6:
                // Implementează tu afișarea disponibilelor!
                cout << "Implementare pentru tema ;)\n";
                break;
            case 0:
                cout << "La revedere!\n";
                break;
            default:
                cout << "Optiune invalida!\n";
        }

    } while(optiune != 0);

    return 0;
}

10. Structuri vs Clase – O Privire în Viitor

#include <iostream>
#include <string>
using namespace std;

// STRUCTURA (în C++ este practic o clasă cu toți membrii publici)
struct StudentStruct {
    // Toți membrii sunt publici implicit
    string nume;
    double media;

    void afiseaza() {
        cout << "Student: " << nume << ", Media: " << media << endl;
    }
};

// CLASĂ (pentru comparație)
class StudentClass {
private:
    string nume;
    double media;

public:
    // Funcții speciale pentru acces (setter/getter)
    void seteazaNume(string n) { nume = n; }
    string obtineNume() { return nume; }

    void seteazaMedia(double m) { 
        if(m >= 1 && m <= 10) {
            media = m; 
        }
    }
    double obtineMedia() { return media; }
};

int main() {
    // Cu structură - acces direct
    StudentStruct s1;
    s1.nume = "Ana";
    s1.media = 9.5;
    s1.afiseaza();

    // Cu clasă - acces controlat
    StudentClass s2;
    s2.seteazaNume("Ion");
    s2.seteazaMedia(15); // Nu se setează - invalid
    s2.seteazaMedia(8.5); // Se setează - valid

    cout << "Student clasa: " << s2.obtineNume() 
         << ", Media: " << s2.obtineMedia() << endl;

    return 0;
}

În concluzie, să-ți spun ceva practic:

Structurile sunt unealta supremă de organizare a datelor în C++. Transformă grupuri de variabile împrăștiate în entități logice și clare. Ele sunt fundamentul pentru modelarea obiectelor din lumea reală în programe.

Dar definirea greșită a unei structuri (cu câmpuri prost organizate sau dependențe ciudate) poate fi, paradoxal, o sursă de confuzie și cod greu de menținut dacă nu gândești cum se folosesc datele împreună.

Așa că ai grijă cum îți definești structurile. Cunoștințe-ti datele: ce aparține împreună? Ce se modifică împreună? Ce se folosește împreună? Pentru că puterea de a organiza date este goală fără abilitatea de a grupa logic ceea ce aparține împreună. Și această putere vine cu o responsabilitate: să fii organizat și intenționat.

Folosirea corectă a structurilor este o parte integrală a programării curate și mentenabile. Ai grijă de ea cu aceeași seriozitate.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *