Pe scurt
O înregistrare grupează câmpuri care descriu același obiect. Un elev poate avea nume, clasă și medie; aceste date au tipuri diferite, dar aparțin aceleiași entități. În C++, struct definește un tip cu astfel de câmpuri. Un vector de structuri permite păstrarea mai multor elevi.
În detaliu
O înregistrare (structură) grupează un număr fix de câmpuri, de tipuri posibil diferite, care descriu aceeași entitate. În C++ se definește cu struct: tipul Elev poate avea câmpurile nume (șir de caractere), clasa (întreg) și medie (real). Un câmp se selectează cu operatorul punct, e.nume; pentru un pointer p către structură, p->clasa este echivalent cu (*p).clasa. O variabilă de tip structură se inițializează enumerând valorile în ordinea câmpurilor: Elev e{"Ana", 9, 8.5};. Atribuirea copie = e; copiază toate câmpurile: schimbarea ulterioară a unui câmp al copiei nu modifică originalul. Înregistrările se pot grupa într-un tablou, Elev v[3], iar v[1].medie este media celui de-al doilea elev. Spre deosebire de un tablou, care are elemente de același tip, o înregistrare combină tipuri diferite.
Exemplul 1 — definirea și copierea.
#include <iostream>
#include <string>
using namespace std;
struct Elev {
string nume;
int clasa;
double medie;
};
int main() {
Elev e{"Ana", 9, 8.5};
Elev copie = e;
copie.medie = 9.5;
cout << e.nume << " " << e.clasa << " " << e.medie << " " << copie.medie;
return 0;
}
Se afișează Ana 9 8.5 9.5. Inițializarea pune în câmpuri, în ordine, "Ana", 9 și 8.5. Prin Elev copie = e; se creează o înregistrare independentă, deci numai media copiei devine 9.5, iar e.medie rămâne 8.5.
Exemplul 2 — un tablou de înregistrări. Pentru elevii Ana (clasa 9, media 8.5), Dan (clasa 9, media 7.25) și Ioana (clasa 10, media 9.1), cel mai bun elev se găsește parcurgând tabloul și păstrând indicele celui cu media maximă: se compară v[i].medie cu v[best].medie. Rezultatul este Ioana, cu media 9.1. Ordonarea descrescătoare după medie dă Ioana, Ana, Dan, iar câmpurile fiecărui elev se mută împreună: sortarea cu sort(v, v + 3, compara) folosește o funcție compara(a, b) care întoarce a.medie > b.medie. Căutarea maximului cere comparații, deci timp proporțional cu și memorie auxiliară constantă.
Exemplul 3 — înregistrare cu pointer. Pentru Elev *p = &e; expresia p->clasa are valoarea 9, iar (*p).nume este Ana. Parantezele sunt obligatorii în a doua formă, pentru că operatorul punct are prioritate mai mare decât *. O modificare prin pointer, p->medie = 9;, schimbă chiar variabila e, spre deosebire de o modificare a unei copii.
Exemplul 4 — înregistrări în subprograme. Un parametru de tip structură transmis prin valoare este o copie: o funcție void majoreaza(Elev e) { e.medie += 1; } nu schimbă elevul din main. Cu parametru prin referință, void majoreaza(Elev &e), modificarea se vede în apelant: pentru Ana, cu media 8.5, apelul face media 9.5. O funcție poate și să întoarcă o înregistrare, Elev citeste(), ale cărei câmpuri sunt citite de la tastatură, iar apelantul le primește împreună. Câmpurile unei înregistrări se afișează separat, pentru că cout << e nu este definit pentru un struct propriu.
Exemplul 5 — calcule pe un tablou de înregistrări. Pentru Ana (8.5), Dan (7.25) și Ioana (9.1) se cer media celor trei medii și numărul elevilor cu media cel puțin 8:
double suma = 0;
int bune = 0;
for (int i = 0; i < 3; ++i) {
suma += v[i].medie;
if (v[i].medie >= 8)
++bune;
}
cout << fixed << setprecision(2) << suma / 3 << ' ' << bune;
Suma mediilor este , iar . Cu două zecimale (antetul <iomanip>) se afișează 8.28 2: Ana și Ioana au media cel puțin 8. Parcurgerea citește fiecare înregistrare o singură dată, deci timpul este proporțional cu numărul elevilor.
Cazuri-limită la inițializare. Dacă inițializarea enumeră doar o parte din câmpuri, Elev e{"Ana"};, câmpurile rămase primesc valoarea zero: e.clasa este 0 și e.medie este 0. Fără nicio inițializare, o variabilă locală de tip Elev are câmpurile numerice nedeterminate, deci se atribuie valori înainte de folosire. Dacă un tablou de elevi este parcurs cu indicele în loc de , se citește în afara tabloului.
Pentru admitere
La o atribuire între două obiecte de același tip struct, câmpurile se copiază; schimbarea ulterioară a unui câmp în copie nu modifică obiectul inițial. Pentru un pointer p către structură, p->clasa este echivalent cu (*p).clasa. Într-un fragment, notează valorile tuturor câmpurilor după fiecare atribuire, într-un tabel cu o coloană pe câmp și o coloană pe obiect. Dacă un subprogram primește structura prin valoare, el modifică o copie; dacă o primește prin referință sau prin pointer, modifică obiectul apelantului. Când un tablou de structuri este sortat, se mută înregistrări întregi, nu câmpuri izolate; dacă un subiect permută doar câmpul medie, numele rămân la poziția veche și asocierea nume–medie se strică.
Exemplu în formatul examenului. Ce se afișează în urma executării secvenței de mai jos?
struct P { int x, y; };
P a{1, 2};
P b = a;
b.x = 5;
a.y = a.x + b.x;
cout << a.x << a.y << b.x << b.y;
- a)
1252 - b)
1652 - c)
5652 - d)
1625
Răspunsul corect este b). După P b = a; obiectul b este o copie: . Atribuirea b.x = 5 face și nu modifică a. Apoi a.y = a.x + b.x calculează , deci . Se afișează în ordine a.x, a.y, b.x, b.y, adică 1, 6, 5, 2. Varianta c) presupune că modificarea lui b.x schimbă și a.x.
Al doilea exemplu în formatul examenului. Ce se afișează în urma executării secvenței de mai jos?
struct P { int x, y; };
void f(P a, P &b) {
a.x = 9;
b.y = 9;
}
P u{1, 2}, w{3, 4};
f(u, w);
cout << u.x << u.y << w.x << w.y;
Răspunsul este 1239. Parametrul a este o copie a lui u, deci atribuirea a.x = 9 nu schimbă u. Parametrul b este o referință la w, deci b.y = 9 modifică chiar variabila w, care devine . Se afișează în ordine u.x, u.y, w.x, w.y, adică 1, 2, 3 și 9, lipite într-un singur număr.
Greșeli frecvente
- Greșit: toate câmpurile unei înregistrări trebuie să aibă același tip.Corect: câmpurile pot avea tipuri diferite.
- Greșit: după
Elev copie = e;, schimbarea luicopie.mediemodifică șie.medie.Corect: copia este independentă de original. - Greșit:
p->clasașip.clasasunt interschimbabile pentru un pointerp.Corect: pentru pointer se folosește->sau(*p)..
Testează-te pe această lecție
Lecția o citești aici, fără cont. Testele pe lecții și capitole sunt în cont, cu grile originale Didaxis și explicația fiecăreia: gratuit 10 grile pe zi, fără limită cu Premium, 49 de lei pe lună pentru fiecare copil.
Înainte și după
Surse și referințe
Redactare proprie, conform programei:
- OMECI 5099/2009, anexa 5, Informatică, p. 4–5, clasa X intensiv; rocnee.eu
- OMECI 5099/2009, anexa 5, Informatică, p. 4–5, clasa XI; plan de încadrare: OMEC 7723/2024, anexa 2, tabelele 1–25, legislatie.just.ro; filiera tehnologică: OMEC 7724/2024, anexa 4, tabelul calificării, legislatie.just.ro
- UNSTPB, Regulament admitere licență 2026, Anexa II-1.2 p. Anx II-14 și Anexa XI-3 p. Anx XI-6–7 (PDF p. 64, 120–121); admitere.pub.ro
- OMECTS 4800/2010, anexa 2, Informatică, p. 3–4; edu.ro
Documente consultate
- Programa școlară de informatică, clasa a X-a (OMECI 5099/2009, anexa 5), CNCE; rocnee.eu
- Programa școlară de informatică, clasa a XI-a (OMECI 5099/2009, anexa 5), CNCE; rocnee.eu
- Programa de bacalaureat la informatică, matematică-informatică (anexa 2 la OMECTS 4800/2010), Ministerul Educației, p. 4–5; edu.ro
- UNSTPB, admitere 2026, anexa XI-3, p. Anx XI-6–7
- cppreference, C++ language, Classes / class and struct, en.cppreference.com/w/cpp/language/classes
Desene: Redactare proprie (desen original), conform OMECTS 4800/2010, Informatică Bac; edu.ro
