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.
Leave a Reply