cheia programarii adevarate
Deja cu ceea ce ai invatat in lectiile anterioare (instructiuni (1/2, 2/2), variabile, instructiunea “daca”) poti construi programe destul de complexe. Pentru a face programe serioase, insa, iti mai lipseste o singura lectie. Este vorba despre o instructiune cu ajutorul careia vei putea, printre altele, scrie in cateva randuri programe care altfel ti-ar fi necesitat zeci sau sute de linii. O instructiune ce iti va deschide poarta catre programarea adevarata, permitandu-ti sa faci si alte lucruri nebanuite. Instructiunea aceasta este while (“cat timp” — in limba romana). Formatul in care ea se scrie in programe este urmatorul:
while (conditie)
{
// instructiuni
…
}
Ca si in cazul instructiunii if (“daca”) invatate in lectia anterioara, in loc de conditie se pot pune verificari de egalitati sau inegalitati intre expresii ce pot contine valori, variabile si operatori. De fapt, instructiunea while seamana mult cu instructiunea if.
Singura diferenta dintre instructiunea scrisa mai sus (adica: while (conditie) {//instructiuni …}) si instructiunea if (conditie) {//instructiuni …} este aceea ca daca conditia conditie este adevarata, in cazul instructiunii if blocul de instructiuni se executa o singura data, in vreme ce in cazul instructiunii while acesta se poate executa de mai multe ori, atata timp cat conditia conditie ramane adevarata (sau, altfel spus, pana cand conditia conditie nu mai este adevarata).
Scrisa in limbaj natural, instructiunea while de mai sus s-ar traduce in “cat timp conditia este adevarata, executa instructiunile scrise intre acolade”.
Evident, daca in blocul de instructiuni scrise intre acolade nu exista nimic care sa afecteze conditia, atunci (in cazul in care aceasta a fost initial adevarata) ea va ramane mereu adevarata, ceea ce inseamna ca blocul de instructiuni se va repeta la nesfarsit. In mod normal, insa, conditia testata contine o variabila a carei valoare se va modifica pe parcursul executarii blocului de intructiuni.
Haide sa vedem un exemplu. Sa zicem ca dorim sa aprindem linia de jos (adica linia cu y egal cu 1) din ecranul nostru de 10×10 puncte.
Bineinteles, putem face asta cu urmatorul program (asa cum am vazut inca din prima lectie):
Aprinde(1, 1);
Aprinde(2, 1);
Aprinde(3, 1);
Aprinde(4, 1);
Aprinde(5, 1);
Aprinde(6, 1);
Aprinde(7, 1);
Aprinde(8, 1);
Aprinde(9, 1);
Aprinde(10, 1);
In regula, dar mai simplu nu se poate?
Ba da. Sa observam, mai intai, ca x-ul transmis instructiunii Aprinde(x, y) variaza de la 1 la 10, in vreme ce y-ul ramane constant (si egal cu 1). Ce-ar fi, atunci, sa luam o variabila (pe care o putem numi chiar x) cu ajutorul careia sa parcurgem intreaga gama de valori 1, 2, 3, …, 10. Putem face asta cu urmatorul pogram:
var x = 1;
while (x <= 10)
{
Aprinde(x, 1);
x = x+1;
}
Hai sa vedem pas cu pas ce face programul acesta:
– 1) Mai intai defineste o variabila numita x, si o initializeaza cu valoarea 1.
– 2) Urmeaza apoi instructiunea “cat timp x este mai mic sau egal cu 10…”
– 3) “… aprinde punctul de la coordonatele (x, 1), si mareste cu 1 valoarea memorata in variabila x“.
Daca ar fi sa derulam pasii 2) si 3), am vedea ca mai intai x este egal cu 1 (de la pasul 1) ), dupa care:
– 2.1) se testeaza daca (x <= 10). Rezultatul este “adevarat” (caci x este egal cu 1), deci se executa pasul 3):
– 3.1) Aprinde(1, 1); x = 1+1;
– 2.2) apoi se testeaza din nou daca (x <= 10). Rezultatul este tot “adevarat” (caci x este acum egal cu 2), deci se executa din nou pasul 3):
– 3.2) Aprinde(2, 1); x = 2+1;
– 2.3) si iar se verifica daca (x <= 10). Cum rezultatul este “adevarat” (x fiind egal acum cu 3), se executa pasul 3):
– 3.3) Aprinde(3, 1); x = 3+1;
… (si asa mai departe… Hai sa trecem peste cativa pasi si sa ajungem direct la pasul in care x are valoarea 10.)
– 2.10) se verifica daca (x <= 10). Rezultatul este “adevarat” (caci x este egal cu 10), deci se executa pasul 3):
– 3.10) Aprinde(10, 1); x = 10+1;
– 2.11) iarasi se verifica daca x este mai mic sau egal cu 10. De asta data, insa, rezultatul este “fals” (caci x are acum valoarea 11), deci nu se mai executa pasul 3), ci se iese din instructiunea while.
Acum testeaza, te rog, programul anterior (cu copy&paste) folosind caseta de mai jos.
Ce s-a intamplat dupa ce ai apasat butonul “Executa programul”? Asa cum ne asteptam, s-a aprins intreaga linie de jos din afisaj.
Bun, dar daca dorim acum sa aprindem pe linia 2 nu intreaga linie, ci doar punctele de pe coloanele 1, 3, 5, 7 si 9?
In primul rand, observam ca ne dorim de fapt sa aprindem toate punctele aflate la coordonatele (x, y), cu proprietatea ca y este egal cu 2, iar x ia pe rand valorile 1, 3, 5, 7, 9 (adica toate valorile impare de la 1 la 10).
Folosind aceasta observatie, programul rezulta cu destula usurinta. Practic putem folosi programul anterior, in care in loc de Aprinde(x, 1) punem Aprinde(x, 2) (caci nu dorim sa aprindem puncte de pe linia 1, ci de pe linia 2). De asemenea, instructiunea Aprinde nu trebuie sa se mai apeleze la fiecare pas, ci doar la pasii pentru care x are valoare impara. Prin urmare, trebuie sa ne folosim de instructiunea if pentru a-i transmite o comanda de genul “executa instructiunea Aprinde(x, 2) doar daca x este numar impar”.
Cum putem testa daca x este numar impar? O varianta posibila este sa verificam restul impartirii lui x la 2. Daca acest rest este egal cu 1, inseamna ca x este impar.
Acum avem tot ce ne trebuie, asa ca hai sa construim programul:
var x = 1;
while (x <= 10)
{
if ( (x % 2) == 1)
{
Aprinde(x, 2);
}
x = x+1;
}
Testeaza-l si pe acesta, te rog. Merge, nu? (Ce-ar fi sa-l modifici astfel incat pe linia 3 sa se aprinda “beculetele” situate pe coloane pare?)
Iata ca deja am ajuns sa scriem programe serioase. Probabil ca un neinitiat s-ar uita la programul anterior ca la un text in chineza scris cu litere arabe. Insa daca ai urmarit cu atentie cele trei lectii anterioare, ai vazut ca lucrurile nu sunt nici pe departe atat de complicate pe cat par, ci totul este perfect logic.
Propun sa incheiem lectia aceasta cu un exemplu ceva mai complicat. Sa zicem ca am dori sa aprindem toate punctele de pe ecranul de 10×10 puncte.
Ce ar trebui sa facem, deci? Bineinteles, am putea sa punem 100 de instructiuni de tip Aprinde(x, y). Sau am putea sa observam ca de fapt tot ce trebuie sa facem este sa avem doua variabile (numite, de exemplu, chiar x si y) cu ajutorul carora sa apelam Aprinde(x, y). Si ar mai trebui sa observam si ca variabila x trebuie sa parcurga toate valorile de la 1 la 10 pentru fiecare valoare a variabilei y (care, la randul ei, ar trebui sa parcurga toate valorile de la 1 la 10).
Aceasta inseamna ca ne vom puteam folosi de primul program de mai sus (cel care aprindea toate punctele de pe linia cu y egal cu 1), numai ca in blocul de insctructiuni din acel while nu vom scrie Aprinde(x, 1), ci Aprinde(x, y), unde y va fi o variabila pe care o vom fi declarat la inceputul programului si o vom fi initializat cu 1.
Va trebui apoi ca intreg acel program sa fie executat din nou pentru y avand valoarea 2. Si apoi pentru y avand valoarea 3. Si asa mai departe, pana la y egal cu 10. Se poate observa ca dorim sa facem cu y o serie de operatii similare celor pe care le facem cu x. Prin urmare, intreg acest program de care vorbim va face parte din blocul de instructiuni al unei instructiuni while ce va testa conditia (y <= 10).
Hai sa vedem cum ar arata programul:
var y;
var x;
y = 1;
while (y <= 10)
{
x = 1;
while (x <= 10)
{
Aprinde(x, y);
x = x+1;
}
y = y+1;
}
Pentru a-l testa, revino la caseta de testare de mai sus, apasa butonul “Reseteaza afisajul”, dupa care introdu acest program si apasa butonul “Executa programul”.
A mers, nu? Ti s-au aprins toate punctele de pe ecran? (Ma intreb daca ai putea sa il modifici astfel incat sa nu-ti aprinda toate punctele, ci sa “deseneze” un soi de “tabla de sah” formata din 10×10 patratele. (Idee: foloseste if-uri; eventual unele in interiorul altora…))
Stiu ca lectia aceasta a fost mai solicitanta decat cele de pana acum. Asa ca te rog sa o parcurgi cu atentie, incercand sa intelegi foarte bine ce se intampla in realitate intr-un program ce contine instructiunea “cat timp” (while), precum si cum se poate imbina aceasta instructiune cu instructiunea “daca” (if) pentru a construi programe serioase. Si bineinteles, nu uita ca imi poti pune orice intrebare (in sectiunea de comentarii de mai jos, sau la adresa de email florin [at] igotopia . ro).