Documente Academic
Documente Profesional
Documente Cultură
ro/cursur i
Cursul 4
1. Principiile de baza ale programarii structurate
Programarea structurata este o orientare in conceperea si alcatuirea programelor, avand ca
obiectiv o mai buna gestionare a complexitatii acestora, tinand cont de particularitatile gandirii umane.
Se stie ca programul are la baza un algoritm, iar acesta poate fi reprezentat printr-o schema logica
sau/si pseudocod. In cazul programelor complexe (care sunt necesare in rezolvarea majoritatii
problemelor reale) numarul de instructiuni este foarte mare si, deci, schema logica poate contine
legaturi foarte complicate intre aceste instructiuni.
La originea programarii structurate sta un articol al lui E.W.Dijkstra, aparut in anul 1968 si
intitulat "Go To Considered Harmful" in care se arata ca, pentru a reduce complexitatea
programelor si a usura intelegerea acestora, este preferabil sa se elimine din programe instructiunea
GOTO (mergi la ...) prin care, in limbajele de programare procedurale, se indica saltul de la o
instructiune la alta. Ulterior, Dijkstra impreuna cu alti cercetatori in domeniul informaticii au conceput
o teorie coerenta a programarii structurate, conform careia la conceperea unui program, este
recomandabil sa se respecte urmatoarele principii:
1. Teorema de structura: orice program poate fi intocmit folosind numai trei structuri de control
fundamentale: structura secventiala, structura alternativa si structura repetitiva.
2. La conceperea programelor se recomanda sa se aplice tehnica de elaborare descendenta (in
engleza Top-Down), numita si tehnica rafinarilor succesive.
3. Domeniile de valabilitate (de vizibilitate) ale variabilelor si structurilor de date trebuie sa fie
limitate.
2. Instructiuni
Executarea unui program este controlata de instructiuni. Spre deosebire de expresii, la care intereseaza
in special valoarea acestora, instructiunile sunt executate pentru efectul lor. Pot exista si instructiuni
care au in componenta lor expresii sau alte instructiuni.
1
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
scrise sub forma de instructiuni numai acele expresii care au efect lateral. Valoarea expresiei ramane,
in acest caz, nefolosita. Instructiuni-expresii:
a) instructiunea de atribuire formata dintr-o expresie de atribuire simpla sau compusa, urmata de
caracterul ';'. Iata exemple de astfel de instructiuni:
a+=3;
x=2*a-3*b;
k+=1+2*(a>b?a:b);
b) instructiunea de incrementare sau decrementare formata dintr-o expresie de incrementare sau
decrementare, urmata de caracterul ';', ca in exemplele urmatoare: instructiunea ++k; are acelasi efect
cu instructiunea k++;.
c) instructiunea de invocare a unei functii formata din expresia de invocare a functiei, urmata de
caracterul ';'. Exemple:
System.out.println("Un sir de caractere");
System.out.print("Alt sir de caractere");
Din punct de vedere sintactic, in astfel de instructiuni putem invoca orice functie. De exemplu, putem
introduce in program "instructiunea" Math.sin(alpha);
prin care este invocata functia matematica sin() pentru a calcula sinusul unghiului alpha. La
compilarea programului nu se va semnala eroare, dar la excutie aceasta instructiune nu va produce nici
un efect, deoarece functia nu are efect lateral, iar valoarea intoarsa de functie (valoarea calculata a
sinusului) nu este folosita. Se constata deci ca, in instructiunile de invocare a unor functii, are sens sa
fie folosite numai functii cu efect lateral.
<instructiunea_1>
<instructiunea_2>
....
<instructiunea_n>
Exista, deci, un numar oarecare (n) de instructiuni, care se executa una dupa alta, in
ordinea in care sunt scrise in program.
2
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
2. 4.2. Structura alternativa (conditionala, de decizie)
Un fragment de program are structura alternativa (numita si structura conditionala sau de decizie),
atunci cand se alege una din doua cai posibile, in functie de modul in care este satisfacuta sau nu o
anumita conditie. Conditie este o expresie booleana. Executarea acestui fragment de program decurge
astfel: se verifica mai intai daca este satisfacuta conditia. Daca ea este satisfacuta, deci expresia
Conditie are valoarea true, se executa Instructiunea 1, iar in caz contrar se executa Instructiunea 2.
Daca <conditie>
atunci <instructiunea_1>
altfel <instructiunea_2>
Sfarsit_daca
• Instrucţiunea if - else
Luarea de decizii reprezintă o componentă de bază a oricărui program. Instrucţiunea if permite unui program să
reacţioneze diferit, în funcţie de rezultatul obţinut la evaluarea unei expresii logice.
Instrucţiunea if are două forme : simplă şi completă.
Exemplu:
Descrieţi în pseudocod un algoritm eficient de afişare a tuturor divizorilor naturali proprii ai unui
număr natural n, citit de la tastatură.
3
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
//Alg. Pseudocod
• Instrucţiunea else-if
Prin intermediul instrucţiunilor de tip else-if se poate testa o întreagă gamă de condiţii care se
exclud reciproc. Programul următor tratează diferenţiat cazurile în care un program este lansat cu
mai multe argumente în linia de comanda.
4
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
else if (args.length == 1) {
System.out.println("Salut " + args[0]);
}
else if (args.length == 2) {
System.out.println("Salut " + args[0] + " "
+ args[1]);
}
else if (args.length == 3) {
System.out.println("Salut " + args[0] + " "
+ args[1] + " " + args[2]);
}
else if (args.length == 4) {
System.out.println("Salut " + args[0] + " "
+ args[1] + " " args[2] + " " + args[3]);
}
else {
System.out.println("Salut " + args[0] + " "
+ args[1] + " " args[2]+ " " + args[3] + " si la toti
ceilalti!");
}
}
}
• Instrucţiunea switch
Limbajul Java oferă o alternativă la folosirea instrucţiunii else-if, deoarece structura acesteia poate
deveni prea complicată atunci când numărul de condiţii este prea mare. Această alternativă este
structura de decizie switch. Instrucţiunea switch este ideală atunci când condiţia de test este o
expresie care poate lua mai multe valori.
Următoarele secvenţe de cod sunt echivalente. Prima secvenţă foloseşte instrucţiunea else if , iar
cea de-a doua, instrucţiunea switch.
if (x == 0) instructiune0();
else if (x == 1) instructiune1();
else if (x == 2) instructiune2();
else if (x == 3) instructiune3();
else if (x == 4) instructiune4();
else instructiuneDefault();
switch (x) {
case 0:
instructiune0();
break;
case 1:
instructiune1();
5
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
break;
case 2:
instructiune2();
break;
case 3:
instructiune3();
break;
case 4:
instructiune4();
break;
default:
instructiuneDefault();
}
În fragmentul anterior, x trebuie să fie o variabilă sau o expresie care poate fi convertită la tipul
int, fără pierderea de informaţii. Înseamnă că variabila trebuie să fie de tipul int, byte, short
sau char. Valoarea variabilei x va fi comparată cu fiecare din etichetele case, până când una
dintre valori va fi egală cu valoarea lui x. Dacă nici o valoare nu se potriveşte, atunci se execută
instrucţiuneDefault.
Odată ce s-a găsit o potrivire, vor fi executate toate instrucţiunile următoare, până când se ajunge la
sfârşitul instrucţiunii switch sau se întâlneşte o instrucţiune break. În mod obişnuit, o instrucţiune
de salt break este inclusă în cadrul fiecărui bloc de tip case.
6
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
Instructiunea while
Instrucţiunea while este întrebuinţată pentru execuţia repetată a unei
instrucţiuni. Execuţia unei instrucţiuni while începe cu evaluarea expresiei
logice. Dacă după evaluarea expresiei se ajunge la rezultatul true, se execută
instrucţiunea. După executarea instrucţiunii se reevaluează expresia logică. În
cazul în care expresia este falsă, execuţia instrucţiunii while se termină. În
caz contrar, while îşi continuă execuţia.
Exemplu
Desi, din punct de vedere al teoriei programarii structurate, ciclul cu test initial este suficient ca
structura repetitiva, in multe limbaje de programare (inclusiv Java), din motive de comoditate a
programarii se admite si o a doua forma de astfel de structura, numita ciclu cu test final. Schema logica
a acestui ciclu este data in figura 4.
Deosebirea dintre cele doua forme de cicluri este ca in ciclul cu test initial
conditia este evaluata inainte de a se executa instructiunea, in timp ce in
ciclul cu test final evaluarea conditiei se face dupa ce instructiunea a fost
deja executata. Aceasta este o deosebire importanta, deoarece in cazul
ciclului cu test initial este posibil ca instructiunea sa nu se execute niciodata
(daca chiar de la prima evaluare conditia nu este satisfacuta), in timp ce la
ciclul cu test final instructiunea din ciclu va fi executata cel putin o data.
Asa dar, ciclul cu test final poate fi inlocuit prin unul echivalent cu test
initial, dar nu si invers. Iata dece, in teoria programarii structurate, ciclul cu
test initial este considerat ca structura de control fundamentala, in timp ce
cel cu test final este o structura d control admisa, dar nu fundamentala.
In pseudocod, ciclul cu test final reprezentat prin schema logica din figura 4 se scrie sub forma
generala:
executa
<instructiune>
cat_timp <conditie>
In unele limbaje (de exemplu in Pascal) pentru ciclul cu test final se adopta o schema logica in care se
deoseste de cea din figura 4 doar prin faptul ca cele doua ramuri DA si NU isi schimba locurile intre
ele, ceeace in pseudocod se scrie sub forma:
7
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
executa
<instructiune>
pana_cand <conditie>
In acest caz, instructiunea din corpul ciclului se va repeta cat timp NU este satisfacuta conditia, deci
pana cand se va constata pentru prima oara ca ea este satisfacuta.
In ambele cazuri, in unele variante de pseudocod instructiunea din corpul ciclului poate fi inlocuita
printr-o secventa de instructiuni. Daca se are in vedere utilizarea limbajului Java, utilizarea unei
secvente nu este necesara, deoarece ea se poate inlocui printr-o singura instructiune compusa, asa cum
se va arata ulterior.
Din examinarea structurilor de control prezentate in acest capitol putem constata ca au o proprietate
importanta: schemele logice ale tuturor structurilor de control admise de metoda programarii structurate
au un singur punct de intrare si un singur punct de iesire.
• Instrucţiunea for
Instrucţiunea for este cea mai des folosită instrucţiune repetitivă. Sintaxa unei instrucţiuni for Java
este :
Exemplu:
int contor;
for (contor=0;contor<100;contor++)
System.out.println(„Contor = „ + contor);
În exemplul de mai sus, se iniţializează contorul iteraţiilor cu valoarea 0. Expresia logică contor
< 100 indică faptul că instrucţiunea trebuie să se execute atâta timp cât valoarea variabilei
contor este mai mică decât 100. În final se incrementează valoarea variabilei contor cu o
unitate. Oricare dintre expresiile iniţializare contor, expr_logica sau incrementare
contor poate să lipsească.
Este posibil ca într-o instrucţiune for să se folosească o listă de condiţii. Elementele care compun
lista de expresii de iniţializare, respectiv lista de expresii de actualizare, sunt separate prin virgule.
8
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
Într-o instrucţiune for nu este posibilă includerea unei condiţii de test multiple. Instrucţiunea
următoare va genera o eroare la compilare:
Următorul program este un exemplu care ilustrează folosirea instrucţiunii for pentru scurtarea
programului de la instrucţiunea while.
2.4.4.Instrucţiunea do-while
do {
Instructiune
} while ( expresie logica )
9
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
Instrucţiunea break realizează ieşirea forţată dintr-un ciclu. Instrucţiunea este folosită în principal
în cadrul unei structuri de decizie de tip switch. Programul ExBreak afişează un mesaj de eroare şi
iese din ciclul for dacă variabila i este mai mare decat 7.
Rezultat:
i=0
i=1
i=2
i=3
i=4
i=5
i=6
i=7
Break ciclu for
Aşa cum break poate fi folosită pentru a întrerupe forţat un ciclu, instrucţiunea continue poate forţa
un program să revină la începutul ciclului. Această instrucţiune poate fi întâlnită doar în cadrul
unor instrucţiuni repetitive (for, while, do while), unde este folosită pentru a termina forţat iteraţia
curentă.
Următorul fragment de cod ilustrează cum pot fi ignorate elementele cu indice par ale unui vector.
for (int i = 0; i < m.length; i++) {
if (m[i] % 2 == 0) continue;
// proceseaza elementele impare...
10
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
Instrucţiunea continue nu este foarte des utilizată în practică, în special datorită faptului că se pot
folosi şi alte metode mai simple pentru a ajunge la acelaşi rezultat. Fragmentul anterior putea fi
scris şi sub următoarea formă:
Atunci când se folosesc instrucţiunile break şi continue în cadrul unor cicluri îmbricate, ele au ca
rezultat terminarea forţată a ciclului interior.
Exemplu:
Rezultat:
1, 1
2, 1
3, 1
4, 1
5, 1
6, 1
7, 1
8, 1
9, 1
Când j este egal cu 2 se iese forţat din ciclul for interior. Ciclul for exterior îşi continuă însă
execuţia.
Pentru a forţa programul să termine execuţia ambelor cicluri, se poate folosi instrucţiunea break
<identificator eticheta>, unde <identificator eticheta> este eticheta asociată ciclului exterior.
11
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
Instrucţiunea return provoacă părăsirea corpului unei metode. În cazul în care return este urmată
de o expresie, valoarea expresiei este folosită ca valoare de retur a metodei. Această valoare poate
fi eventual convertită către tipul de valoare de retur declarat al metodei, dacă acest lucru este
posibil. Dacă nu este posibil, va fi semnalată o eroare de compilare.
Este o eroare de compilare specificarea unei valori de retur într-o instrucţiune return din interiorul
unei metode care este declarată void, cu alte cuvinte care nu întoarce nici o valoare.
Instrucţiunea return fără valoare de retur poate fi folosită şi pentru a părăsi execuţia unui
iniţializator static.
Tehnica rafinarilor succesive ofera o cale de a parcurge acest drum de la CE la CUM in mai multi pasi,
astfel incat sa se porneasca de la un numar mic de enunturi (pseudoinstructiuni) de nivel de
abstractizare ridicat, dupa care - la fiecare pas de rafinare - fiecare din aceste instructiuni se
descompune in mai multe instructiuni de nivel de abstractizare mai coborat (mai "concrete"), pana cand
se ajunge la instructiuni scrise direct in limbajul de programare folosit (de exemplu in Java). Se pune
deci un accent deosebit pe abstractizarea datelor si a instructiunilor. Dupa cum arata E.W.Dijkstra,
abstractizarea este calea prin care omul stapaneste complexitatea.
Daca privim schemele logice din sectiunea anterioara, constatam cu usurinta ca atat blocurile care
contin instructiuni, cat si structurile de control admise de metoda programarii structurate au fiecare un
singur punct de intrare si un singur punct de iesire. Aceasta inseamna ca orice bloc care contine o
instructiune poate fi inlocuit in schema respectiva printr-o structura de control. Ca urmare se poate
aplica urmatoarea cale de elaborare a programului specifica tehnicii rafinarilor succesive:
- initial se considera ca programul este alcatuit dintr-o singura pseudoinstructiune, de inalt nivel de
abstractizare, care consta chiar din specificatia problemei pe care o va "rezolva" programul respectiv;
- la pasul de rafinare urmator, aceasta "problema" se descompune in doua sau mai multe
"subprobleme"; aceasta inseamna ca unica pseudoinstructiune existenta initial se inlocuieste prin una
din structurile admise de metoda programarii structurate (structura secventiala, alternativa sau
repetitiva); aceasta structura contine in ea una sau mai multe instructiuni sau pseudoinstructiuni;
- la pasii de rafinare urmatori, fiecare pseudoinstructiune care nu are corespondenta directa in
limbajul de programare utilizat se inlocuieste, de asemenea, prin una din structurile de control admise;
textul ei poate fi, totusi, mentinut sub forma de comentariu, astfel incat sa se inteleaga mai usor
programul;
12
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
- se continua acest proces de rafinari succesive, pana cand toate instructiunile astfel obtinute au
corespondent in limbajul d programare utilizat.
{
<declaratie_de_variabile sau instructiune>*
}
Blocul se comporta ca o instructiune compusa, in sensul ca peste tot unde sintaxa limbajului prevede o
instructiune, aceasta poate fi inlocuita printr-un bloc. Aceasta inseamna, de asemenea, ca orice
instructiune din interiorul unui bloc poate fi ea insesi un bloc. Se observa ca insusi corpul metodei
main() este un bloc.
Din punct de vedere al programarii structurate, blocul este o structura de control secventiala.
6.1. Elaborarea unui program incepe intotdeauna cu formularea problemei de rezolvat, deci cu
stabilirea obiectivelor pe care trebuie sa le realizeze programul (CE trebuie realizat). Desi pare
simpla, aceasta etapa este deosebit de importanta, deoarece formularea incorecta a obiectivelor poate
orienta elaborarea programului pe o cale gresita, cu risipa mare de resurse.
6.2. Urmatoarea etapa este analiza problemei. In aceasta etapa, se face apel la cunostintele din
domeniul caruia ii apartine problema data (matematica, inginerie, contabilitate etc.) si se stabileste
metoda de rezolvare, fara a o formula, deocamdata, sub forma de algoritm. Cu aceasta ocazie se
reanalizeaza formularea initiala a problemei si - daca se constata ca nu este suficient de clara sau chiar
este incorecta - se cere reformularea acesteia.
13
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
6.3. In etapa de concepere a programului: datele si structurile de date cu care se opereaza, precum si
operatiile care se fac asupra acestora (algoritmul de prelucrare). Algoritmul poate fi reprezentat sub
forma de schema logica, sau in pseudocod.
6.4. Codificare - se scrie programul folosind un limbaj de programare (in cazul nostru limbajul Java).
Programul astfel scris se compileaza, eliminandu-se erorile indicate de compilator.
6.5. Urmatoarea etapa este testarea programului astfel obtinut. In acest scop, se executa programul cu
date astfel alese, incat sa se verifice cum se comporta acesta in diferite situatii care pot sa apara in
practica, iar rezultatele sa poata fi verificate. Daca la testare s-au obtinut rezultate corecte, se poate
trece la etapa de utilizare a acestuia. Daca insa rezultatele testarii nu sunt corecte, inseamna ca exista in
program erori de conceptie, care trebuie depistate si eliminate, ceeace poate necesita reluarea fazei de
conceptie, sau chiar a celei de analiza sau de formulare a problemei.
Din cele prezentate mai sus, se observa ca elaborarea unui program nu este o succesiune "liniara" de
etape, ci este un proces iterativ, in care in orice etapa se poate reveni la oricare din cele anterioare.
In cazul tehnicii descendente de elaborare a programelor, aceste etapele de formulare a problemei,
analiza si conceptie se parcurg nu numai pentru problema de ansamblu, ci si pentru fiecare din
subproblemele in care aceasta se descompune pe parcursul conceperii programului.
Exercitii propuse
Ex1:
Se consideră algoritmul alăturat descris în
pseudocod.
S-a notat cu x%y restul împărţirii numărului natural x
la numărul natural nenul y şi cu [z] partea întreagă a
numărului real z.
a. Scrieţi numărul care se va afişa dacă se citeşte
valoarea 123456.
b. Scrieţi o valoare cu exact 5 cifre care poate fi
citită pentru variabila n astfel încât numărul
afişat să fie format din toate cifrele lui n, scrise
în ordine inversă.
c. Corespunzător algoritmului dat, scrieţi programul
Java si schema logica
d. Scrieţi în pseudocod un algoritm echivalent cu
cel dat în care să se înlocuiască structura cât
timp... execută cu o structură repetitivă cu
test final
14
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
Ex2:
Se consideră algoritmul alăturat, descris în
pseudocod.
S-a notat cu [z] partea întreagă a numărului real z, iar cu
x%y restul împărţirii numărului natural x la numărul natural
nenul y.
a. Scrieţi numărul care se va afişa dacă se citeşte
numărul n=3072941.
b. b) Scrieţi un număr format din exact 5 cifre, ele
fiind în ordine strict crescătoare, care poate fi citit
astfel încât executarea algoritmului să determine
afişarea unui număr egal cu cel citit.
c. Scrieţi în pseudocod un algoritm echivalent cu cel
dat în care să se înlocuiască fiecare structură cât
timp… execută cu câte o structură repetitivă cu
test final.
d. Corespunzător algoritmului dat, scrieţi programul
Java si schema logica
Ex3:
Se consideră algoritmul alăturat, descris în pseudocod.
S-a notat cu [x] partea întreagă a numărului real x.
a) Scrieţi ce se afişează dacă se citesc, în această ordine,
valorile: 5, 8, 12, 15, 10, 25, 9, 8, 30, 10.
b) Dacă pentru n se citeşte valoarea 3 scrieţi un şir de date de
intrare astfel încât ultima valoare care se afişează să fie 3.
c) Corespunzător algoritmului dat, scrieţi programul Java si
schema logica
d) Scrieţi un algoritm pseudocod echivalent cu cel dat în care
structura repetă...până când să fie înlocuită cu o structură
repetitivă cu test iniţial.
Ex4:
Se consideră algoritmul alăturat, descris în
pseudocod.
S-a notat cu [z] partea întreagă a numărului real z, iar cu
x%y restul împărţirii numărului natural x la numărul natural
nenul y.
a. Scrieţi numărul care se va afişa dacă se citesc
pentru n valoarea 528791 şi pentru k valoarea 6.
b. Dacă pentru k se citeşte valoarea 8 scrieţi toate
valorile formate din exact 5 cifre care se pot citi pentru variabila
n, astfel încât rezultatul afişat să fie, de fiecare dată, 2008.
c. Scrieţi în pseudocod un algoritm echivalent cu cel dat
care să utilizeze în locul structurii cât timp ...
execută o structură repetitivă cu test final.
d. Corespunzător algoritmului dat, scrieţi programul Java si
schema logica
15
Informatica aplicata-note de curs constructii20092010@gmail.com; http://scdsd.bluepink.ro/cursur i
Ex5:
Se consideră algoritmul alăturat, descris în pseudocod.
a. Dacă se citeşte pentru n valoarea 10, scrieţi
valorile care se afişează, în forma rezultată în urma
executării algoritmului;
b. Scrieţi o valoare formată din exact două cifre care,
dacă se citeşte pentru n, determină ca printre
tripletele de valori afişate să existe unul alcătuit din
trei numere consecutive.
c. Corespunzător algoritmului dat, scrieţi programul
Java si schema logica
d. Scrieţi în pseudocod un algoritm echivalent cu cel
dat care să utilizeze exact două structuri repetitive.
16