Structuri Repetitive și Tipul lor de Test: Cum Înveți Calculatorul Să “Repete” – Materie BAC

Bun, hai să vorbim despre unul dintre cele mai puternice concepte din programare: BUCLELE (Structurile Repetitive). Nu e doar despre repetiție (cuvânt plictisitor) și cicluri. E despre cum transformi o sarcină monotonă de mii de ori într-un simplu set de instrucțiuni. E un proces atât de eficient încât dacă ar fi să-l faci manual, ți-ar lua o viață întreagă. Dar aici intervine și partea strategică: alegerea corectă a tipului de buclă pentru situația potrivită.

1. Ce sunt Structurile Repetitive? “Robotul Tău Personal de Repetiție”

Gândește-te la ele ca la un angajat extrem de obediente și nerăbdător să repete aceeași acțiune: poate număra ouăle dintr-un depozit, poate saluta 100 de oameni la rând, poate verifica temperatura la fiecare 10 minute. Să le înțelegem esența.

Definiția Structurilor Repetitive:
O structură repetitivă este un bloc de instrucțiuni care se execută de mai multe ori, în funcție de o condiție. Fără bucle, ar trebui să scrii aceleași linii de cod de mii de ori!

Analogie cu un Parrot Antrenat:

“Spune ‘Salut’ de 5 ori!”

Fără buclă: (programatorul scrie manual)

  1. cout << “Salut” << endl;
  2. cout << “Salut” << endl;
  3. cout << “Salut” << endl;
  4. cout << “Salut” << endl;
  5. cout << “Salut” << endl;

Cu buclă: (inteligent!)
Pentru (i de la 1 la 5) {
cout << “Salut” << endl;
}

DE CE sunt așa importante?
Pentru că lumea reală este plină de repetiții:

  • Procesezi toate produsele dintr-un magazin
  • Verifici toți studenții dintr-o listă
  • Citești toate liniile dintr-un fișier
  • Aștepți până când utilizatorul apasă butonul “Exit”

2. Cele Trei Tipuri Fundamentale de Bucle (Cei “Trei Muscheți” ai Repetiției)

Există trei tipuri principale, fiecare cu superputerile și limitele ei.

TIPUL 1: BUCLA CU TEST INITIAL – while (C++/Pascal) – “Verifică înainte să sari”

  • Cum funcționează: VERIFICĂ condiția, APOI execută (dacă condiția e adevărată)
  • Motto: “Dacă e OK, atunci fac. Altfel, nici nu încep.”
  • Riscuri: Dacă condiția e falsă de la început, bucla NU se execută DELOC
  • Analogie: Intri la film DOAR DACA ai bilet. Dacă nu ai bilet, nici nu te duci la intrare.

În C++ (while):

#include <iostream>
using namespace std;

int main() {
    int numarMagic = 7;
    int incercare;

    cout << "Ghiceste numarul magic (1-10): ";
    cin >> incercare;

    // TEST INIȚIAL: verifică înainte de a intra în buclă
    while (incercare != numarMagic) {  // Dacă nu ai ghicit...
        cout << "Gresit! Mai incearca: ";
        cin >> incercare;  // ...îți mai dai o șansă
    }

    cout << "BRAVO! Ai ghicit numarul magic: " << numarMagic << endl;

    return 0;
}

În Pascal (while):

program BuclaWhile;
var
  numarMagic, incercare: integer;
begin
  numarMagic := 7;

  write('Ghiceste numarul magic (1-10): ');
  readln(incercare);

  // TEST INIȚIAL: verifică înainte de a intra în buclă
  while incercare <> numarMagic do  // Cât timp nu ai ghicit...
  begin
    write('Gresit! Mai incearca: ');
    readln(incercare);  // ...îți mai dai o șansă
  end;

  writeln('BRAVO! Ai ghicit numarul magic: ', numarMagic);
end.

Când folosești while?

  • Când NU știi exact de câte ori trebuie să repeți
  • Când procesezi date până întâlnești o condiție de stop
  • Când citești din fișier până la sfârșit
  • Când aștepți o acțiune de la utilizator

TIPUL 2: BUCLA CU TEST FINAL – do-while (C++) / repeat-until (Pascal) – “Sari înainte să verifici”

  • Cum funcționează: Execută O DATĂ, APOI verifică condiția
  • Motto: “Fac cel puțin o dată, apoi mă întreb dacă mai fac.”
  • Particularitate: Se execută CEL PUȚIN O DATĂ, chiar dacă condiția e falsă de la început
  • Analogie: Înoti în piscină și te întrebi după: “A fost apă în piscină?” Da, pentru că deja ai înotat!

În C++ (do-while):

#include <iostream>
using namespace std;

int main() {
    char raspuns;

    do {  // FAI: execută cel puțin o dată
        cout << "Vrei sa afli un secret? (d/n): ";
        cin >> raspuns;

        if (raspuns == 'd' || raspuns == 'D') {
            cout << "SECRET: Calculatorul nu stie sa 'gandeasca'!\n";
        }

    } while (raspuns == 'd' || raspuns == 'D');  // Cât timp răspunsul e 'd'

    cout << "Ok, păstrăm secretul...\n";

    return 0;
}

În Pascal (repeat-until):

program BuclaRepeat;
var
  raspuns: char;
begin
  repeat  // REPETĂ: execută cel puțin o dată
    write('Vrei sa afli un secret? (d/n): ');
    readln(raspuns);

    if (raspuns = 'd') or (raspuns = 'D') then
      writeln('SECRET: Pascal a fost numit dupa matematicianul Blaise Pascal!');

  until (raspuns <> 'd') and (raspuns <> 'D');  // Până când răspunsul NU e 'd'

  writeln('Ok, pastram secretul...');
end.

Când folosești do-while/repeat-until?

  • Când vrei să execuți bucla cel puțin o dată
  • La meniuri interactive (“Vrei să continui?”)
  • La validarea input-ului (cere până primești ceva valid)
  • La jocuri (“Mai joci o rundă?”)

OBSERVAȚIE CRUCIALĂ:

  • C++: do {...} while(conditie); → se repetă CÂT TIMP condiția e adevărată
  • Pascal: repeat ... until conditie; → se repetă PÂNĂ CÂND condiția e adevărată
  • SUNT OPUSE!
  • while(x < 5) în C++ = repetă cât timp x este mai mic decât 5
  • until x >= 5 în Pascal = repetă până când x devine mai mare sau egal cu 5

TIPUL 3: BUCLA CU CONTOR – for (C++/Pascal) – “Știi exact câte repetiții vrei”

  • Cum funcționează: Cunoaște dinainte numărul de repetiții
  • Motto: “Fac exact de N ori, nu mai mult, nu mai puțin.”
  • Structură tipică: for(initializare; conditie; modificare_contor)
  • Analogie: Un chef care spune: “Fă exact 5 omlete. Prima e pentru masa 1, a doua pentru masa 2…”

În C++ (for):

#include <iostream>
using namespace std;

int main() {
    // Afișează tabla înmulțirii cu 7
    cout << "Tabla inmultirii cu 7:\n";

    for (int i = 1; i <= 10; i++) {  // i++ = i = i + 1
        // i ia valorile: 1, 2, 3, ..., 10
        cout << "7 x " << i << " = " << 7 * i << endl;
    }

    // Contor descrescător
    cout << "\nLansare in: ";
    for (int secunda = 10; secunda >= 1; secunda--) {  // secunda--
        cout << secunda << "... ";
    }
    cout << "POC! Lansat!\n";

    return 0;
}

În Pascal (for):

program BuclaFor;
var
  i, secunda: integer;
begin
  // Afișează tabla înmulțirii cu 7
  writeln('Tabla inmultirii cu 7:');

  for i := 1 to 10 do  // de la 1 până la 10, crescător
  begin
    writeln('7 x ', i, ' = ', 7 * i);
  end;

  // Contor descrescător (în Pascal folosim downto)
  write('Lansare in: ');
  for secunda := 10 downto 1 do  // de la 10 până la 1, descrescător
  begin
    write(secunda, '... ');
  end;
  writeln('POC! Lansat!');
end.

Când folosești for?

  • Când știi exact de câte ori trebuie să repeți
  • Când parcurgi un vector/matrice (îți știi dimensiunea)
  • Când simulezi ceva cu un număr fix de iterații
  • Când generezi serii de numere

3. Comparație și Situații Practice

Tabel comparativ:

Caracteristicăwhile (test inițial)do-while/repeat-until (test final)for (cu contor)
Când verificăÎnainte de execuțieDupă execuțieÎnainte de execuție
Execută dacă condiția e falsă de la început?NUDA (o dată)NU
Când o foloseștiNumăr necunoscut de repetițiiCel puțin o execuție garantatăNumăr cunoscut de repetiții
Contor integrat?Nu (trebuie să-l gestionezi manual)Nu (trebuie să-l gestionezi manual)Da (gestiune automată)
Risc de buclă infinităMare (dacă uiți să modifici condiția)Mare (dacă uiți să modifici condiția)Mic (dacă setezi corect condiția)

4. Bucle Îmbricate (Bucle în Bucle) – “Matrioșka de Repetiții”

Poți pune bucle în interiorul altor bucle pentru a rezolva probleme complexe.

Exemplu: Tabla înmulțirii completă (1-10)

În C++:

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

int main() {
    cout << "Tabelul inmultirii complete:\n\n";

    // Bucla pentru primul factor (rânduri)
    for (int i = 1; i <= 10; i++) {
        // Bucla pentru al doilea factor (coloane)
        for (int j = 1; j <= 10; j++) {
            cout << setw(4) << i * j;  // Afișează produsul
        }
        cout << endl;  // Linie nouă după fiecare rând
    }

    return 0;
}

În Pascal:

program BucleImbricate;
var
  i, j: integer;
begin
  writeln('Tabelul inmultirii complete:');
  writeln;

  // Bucla pentru primul factor (rânduri)
  for i := 1 to 10 do
  begin
    // Bucla pentru al doilea factor (coloane)
    for j := 1 to 10 do
    begin
      write(i * j:4);  // Afișează produsul
    end;
    writeln;  // Linie nouă după fiecare rând
  end;
end.

5. Pericolele Buclelor: Buclele INFINITE și Cum Să Le Evităm

O buclă infinită e ca un hamster care aleargă într-un cerc și nu mai iese niciodată. Calculatorul se blochează!

Cum se creează (din greșeală):

// EXEMPLU PERICULOS!
int x = 1;
while (x < 10) {  // Condiție care rămâne mereu adevărată
    cout << "Salut ";  // Se execută la infinit!
    // UITAT: x++;  // Trebuia să mărești x!
}

Cum previi:

  1. Pentru while și do-while:
  • Asigură-te că ceva se modifică în interiorul buclei
  • Fii sigur că condiția va deveni falsă la un moment dat
  1. Pentru for:
  • Verifică dacă contorul merge în direcția corectă
   // GREȘIT: vrei să mergi de la 1 la 10, dar...
   for (int i = 1; i <= 10; i--) {  // i-- în loc de i++
       // i va scădea la infinit (1, 0, -1, -2, ...)
   }

6. Cuvinte Cheie Speciale: break și continue

break – “Ieși Imediat din Bucată!”

  • Iese complet din buclă, indiferent de condiție
  • Ca un buton de panică

În C++:

for (int i = 1; i <= 100; i++) {
    if (i == 13) {
        cout << "Am gasit numarul ghinionist! Oprește tot!";
        break;  // Ieși din buclă, chiar dacă trebuia să mergi până la 100
    }
    cout << i << " ";
}

În Pascal:

for i := 1 to 100 do
begin
    if i = 13 then
    begin
        writeln('Am gasit numarul ghinionist! Opreste tot!');
        break;  // Ieși din buclă
    end;
    write(i, ' ');
end;

continue – “Sari Peste Asta și Mergi Mai Departe!”

  • Sari peste restul iterației curente, dar continui cu următoarea
  • Ca să spui: “Asta nu mă interesează, trec la următorul”

În C++:

for (int i = 1; i <= 10; i++) {
    if (i % 2 == 0) {  // Dacă i este par
        continue;  // Sari peste numerele pare
    }
    cout << i << " ";  // Afișează doar numere impare: 1 3 5 7 9
}

În Pascal:

for i := 1 to 10 do
begin
    if i mod 2 = 0 then  // Dacă i este par
    begin
        continue;  // Sari peste numerele pare
    end;
    write(i, ' ');  // Afișează doar numere impare: 1 3 5 7 9
end;

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

Buclele sunt forța musculară a programării. Transformă sarcini imposibil de lungi în rutine simple și eficiente. Ele sunt cea mai bună demonstrație a puterii automate a calculatoarelor.

Dar alegerea greșită a tipului de buclă poate fi, paradoxal, o sursă de ineficiență sau erori dacă nu e făcută cu înțelegerea condițiilor și a obiectivelor tale.

Așa că ai grijă ce buclă alegi. Cunoștințe-ti nevoile: știi exact numărul de repetiții? Ai nevoie să execuți cel puțin o dată? Te poți opri doar când apare o anumită condiție? Pentru că puterea de a automatiza repetiția este goală fără abilitatea de a alege instrumentul corect pentru sarcina corectă. Și această putere vine cu o responsabilitate: să fii strategic și precis.

Managementul corect al structurilor repetitive este o parte integrală a programării eficiente. Ai grijă de ea cu aceeași seriozitate.

Comments

Leave a Reply

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