Documente Academic
Documente Profesional
Documente Cultură
IMPLEMENTAREA STRUCTURILOR
DE CONTROL
3.1. Implementarea structurii secveniale
3.2. Implementarea structurii de decizie
Algoritmul proiectat pentru rezolvarea unei anumite probleme trebuie implementat ntr-un limbaj de
programare; prelucrarea datelor se realizeaz cu ajutorul instruciunilor. Instruciunea descrie un proces de
prelucrare pe care un calculator l poate executa. O instruciune este o construcie valid (care respect
sintaxa limbajului) urmat de ; . Ordinea n care se execut instruciunile unui program definete aa-numita
structur de control a programului.
Limbajele moderne sunt alctuite pe principiile programrii structurate. Conform lui C. Bohm i G.
Jacobini, orice algoritm poate fi realizat prin combinarea a trei structuri fundamentale:
structura secvenial;
structura alternativ (de decizie, de selecie);
structura repetitiv (ciclic).
secvenial
Sn
S2
S1
CAPITOLUL 3
for (;;)
{
. . . .
}
Instruciunea expresie
Sintaxa:
sau:
expresie;
apel_funcie;
Exemple:
int b, a=9;
double c;
b=a+9;
cout<<a;
c=sqrt(a);
clrcsr();//apelul funciei predefinite care terge ecranul; prototipul n headerul conio.h
{
declaratii;
instr1;
instr2;
. . . .
}
ntr-un bloc se pot declara i variabile care pot fi accesate doar n corpul blocului. Instruciunea bloc este
utilizat n locurile n care este necesar prezena unei singure instruciuni, ns procesul de calcul este mai
complex, deci trebuie descris n mai multe secvene.
Instruciunea if:
Sintaxa:
if (expresie)
instruciune1;
[ else
instruciune2; ]
Ramura else este opional.
La ntlnirea instruciunii if, se evalueaz expresie (care reprezint o condiie) din paranteze. Dac
valoarea expresiei este 1 (condiia este ndeplinit) se execut instruciune1; dac valoarea expresiei este
0 (condiia nu este ndeplinit), se execut instruciune2. Deci, la un moment dat, se execut doar una
dintre cele dou instruciuni: fie instruciune1, fie instruciune2. Dup execuia instruciunii if se trece la
execuia instruciunii care urmeaz acesteia.
Observaii:
1. Instruciune1 i instruciune2 pot fi instruciuni compuse (blocuri), sau chiar alte instruciuni if
(if-uri imbricate).
2. Deoarece instruciunea if testeaz valoarea numeric a expresiei (condiiei), este posibil prescurtarea:
3.
Exemplu:
if (n>0)
2
CAPITOLUL 3
4. Pentru claritatea programelor surs se recomand alinierea instruciunilor prin utilizarea tabulatorului
orizontal.
5. Deseori, apare construcia:
if (expresie1)
instruciune1;
else
if (expresie2)
instruciune2;
else
if (expresie3)
instruciune3;
. . . . . . . . .
else
instruciune_n;
Expresiile sunt evaluate n ordine; dac una dintre expresii are valoarea 1, se execut instruciunea
corespunztoare i se termin ntreaga nlnuire. Ultima parte a lui else furnizeaz cazul cnd nici una
dintre expresiile 1,2,. . ., n-1 nu are valoarea 1.
6. n cazul n care instruciunile din cadrul if-else sunt simple, se poate folosi operatorul condiional.
Exerciii:
1. S se citeasc de la tastatur un numr real. Daca acesta se afl n intervalul [-1000, 1000], s se afiseze
1, dac nu, s se afiseze -1.
#include <iostream.h>
void main()
{
double nr; cout<<Astept numar:; cin>>nr;
int afis = (nr>= -1000 && nr <= 1000 ? 1 : -1); cout<<afis;
/* int afis;
if (nr >= -1000 && nr <= 10000)
afis = 1;
else afis= -1;
}
cout<<afis; */
2. S se calculeze valoarea funciei f(x), tiind c x este un numr real introdus de la tastatur:
- 6x + 20
,
dac x [- , -7 ]
f(x) =
x + 30
,
dac x (-7, 0]
x
dac x>0
#include <iostream.h>
Sau:
#include <math.h>
void main()
{
double x,f;cout<<x=;cin>>x;
if (x <= -7)
f= -x* 6 +20;
else
if ( x<=0 )
f= x+30;
else x=sqrt(x);
cout<<f=<<f<<\n;
}
#include <iostream.h>
#include <math.h>
void main()
{
double x,f;cout<<x=;cin>>x;
if (x <= 7)
f= -x* 6 +20;
if (x>=-7 && x<=0 )
f= x+30;
if (x>0) x=sqrt(x);
cout<<f=<<f<<\n;
}
CAPITOLUL 3
Uneori, construcia if-else este utilizat pentru a compara valoarea unei variabile cu diferite valori constante,
ca n programul urmtor:
3. Se citete un caracter reprezentnd un operator aritmetic binar simplu. n funcie de caracterul citit, se
afieaz numele operaiei pe care acesta o poate realiza.
#include <iostream.h>
void main()
{
char oper;
cout<<Introdu operator aritmetic, simplu, binar:; cin>>oper;
if (oper == +)
cout<<Operatorul de adunare!\n;
else if (oper==- )
cout<<Operatorul de scadere!\n;
else if (oper==* )
cout<<Operatorul de inmultire!\n;
else if (oper==/ )
cout<<Operatorul de impartire!\n;
else if (oper==% )
cout<<Operatorul rest!\n;
else cout<<Operator ilegal!!!\n;
}
Instruciunea switch
n unele cazuri este necesar o decizie multipl special. Instruciunea switch permite acest lucru.
Reprezentare prin schema logic (figura 3.2):
Reprezentare prin pseudocod:
test_expresie
instruciune1
break
Dac expresie=expr_const_1
instruciune1;
[ieire;]
Altfel dac expresie=expr_const_2
instruciune2;
[ieire;]
instruciune2
break
instruciune_n
CAPITOLUL 3
case expresie_const_n-1:
instructiune_n-1;
[break;]
[ default: instructiune_n; ]
}
Este evaluat expresie (expresie aritmetic), iar valoarea ei este comparat cu valoarea expresiilor
constante 1, 2, etc. (expresii constante=expresii care nu conin variabile). n situaia n care valoarea
expresie este egal cu valoarea expr_const_k, se execut instruciunea corespunztoare acelei ramuri
(instruciune_k). Dac se ntlnete instruciunea break, parcurgerea este ntrerupt, deci se va trece
la execuia primei instruciuni de dup switch. Dac nu este ntlnit instruciunea break, parcurgerea
continu. Break-ul cauzeaz deci, ieirea imediat din switch.
n cazul n care valoarea expresiei nu este gsit printre valorile expresiilor constante, se execut cazul
marcat cu eticheta default (cnd acesta exist). Expresiile expresie, expresie_const_1,
expresie_const_2,etc., trebuie s fie ntregi. n exemplul urmtor, ele sunt de tip char, dar o dat de
tip char este convertit automat n tipul int.
Exerciiu: S rescriem programul pentru problema 3, utiliznd instruciunea switch.
#include <iostream.h>
void main()
{
char oper;
cout<<Introdu operator aritmetic, simplu, binar:;
cin>>oper;
switch (oper)
{
case (+):
cout<<Operatorul de adunare!\n;
break;
case (-):
cout<<Operatorul de scadere!\n;
break;
case (*):
cout<< Operatorul de inmultire!\n;
break;
case (/):
cout<<Operatorul de impartire!\n;
break;
case (%):
cout<<Operatorul rest!\n;
break;
default:
cout<<Operator ilegal!\n;
}
}
CAPITOLUL 3
La ntlnirea acestei instruciuni, se evalueaz expresie. Dac aceasta are valoarea 1 - sau diferit de 0 (condiie ndeplinit), se execut instruciune. Se revine apoi n punctul n care se evalueaz din nou
valoarea expresiei. Dac ea este tot 1, se repet instruciune, .a.m.d. Astfel, instruciunea (corpul
ciclului) se repet att timp ct expresie are valoarea 1. n momentul n care expresie ia valoarea 0
(condiie nendeplinit), se iese din ciclu i se trece la urmtoarea instruciune de dup while.
Observaii:
1. n cazul n care la prima evaluare a expresiei, aceasta are valoarea zero, corpul instruciunii while nu va
fi executat niciodat.
2. Instruciune din corpul ciclului while poate fi compus (un bloc), sau o alt instruciune ciclic.
3. Este de dorit ca instruciunea din corpul ciclului while s modifice valoarea expresiei. Dac nu se
realizeaz acest lucru, corpul instruciunii while se repet de un numr infinit de ori.
Exemplu:
int a=7;
while (a==7)
cout<<Buna ziua!\n;
Instruciunea for
n majoritatea limbajelor de programare de nivel nalt, instruciunea for implementeaz structura ciclic cu
numr cunoscut de pai (vezi reprezentarea prin schema logic i pseudocod din capitolul 1). n limbajul C
instruciunea for poate fi utilizat ntr-un mod mult mai flexibil.
Reprezentare prin schema logic (figura 3.3.):
Reprezentare n pseudocod:
evaluare expresie1
CT TIMP expresie2 REPET
NCEPUT
instruciune
evaluare expresie3
SFRIT
1
instruciune
evaluare expresie3 (particular incrementare contor)
Figura 3.3. Structura ciclic cu test iniial
Sintaxa:
for (expresie1; expresie2; expresie3)
instructiune;
instructiune;
CAPITOLUL 3
Se execut instruciune. Se evalueaz apoi expresie. Dac aceasta are valoarea 1, se execut
instruciune. Se testeaz din nou valoarea expresiei. Se repet instruciune ct timp valoarea
expresiei este 1 (condiia este ndeplinit). n cazul instruciunii do-while, corpul ciclului se execut cel puin
o dat.
Exerciii:
1. Se citete cte un caracter, pn la ntlnirea caracterului @. Pentru fiecare caracter citit, s se afieze un
mesaj care s indice dac s-a citit o liter mare, o liter mic, o cifr sau un alt caracter. S se afieze cte
litere mari au fost introduse, cte litere mici, cte cifre i cte alte caractere. Se prezint trei modaliti de
implementare (cu instruciunea while, cu instruciunea for i cu instruciunea do-while).
#include <iostream.h>
#include <conio.h>
void main()
{ char c; clrscr();
int lmic=0, lmare=0, lcif=0;
int altcar=0;
cout<<"Atept car.:"; cin>>c;
while (c!='@'){
if (c>='A' && c<='Z') {
cout<<"Lit. mare!\n";
lmare; }
else if (c>='a' && c<='z') {
cout<<"Lit. mic!\n";
lmica; }
else if (c>='0' && c<='9') {
cout<<"Cifr!\n";
lcif; }
else {
cout<<"Alt car.!\n";
altcar; }
cout<<"Atept car.:";cin>>c;
}
cout<<"Ai introdus \n";
cout<<lmare<<" litere mari, ";
cout<<lmic<<" litere mici\n";
cout<<lcif<<" cifre i \n";
cout<<altcar<<" alte carctere\n";
#include <iostream.h>
Pentru implementarea
aceluiai algoritm se poate utiliza instruciunea for. n cadrul acesteia, expresie1 i expresie3 lipsesc, ns prezen
#include <conio.h>
void main()
{ char c;clrscr();
intlmic=0,lmare=0,lcif=0;int altcar=0;
cout<<"Atept caract.:"; cin>>c;
for( ; c!='@'; ){
// corp identic
}
cout<<"Ai introdus \n";
cout<<lmare<<" litere mari, ";
cout<<lmic<<" litere mici\n";
cout<<lcif<<" cifre i \n";
cout<<altcar<<" alte carctere\n";
getch();
}
O alt variant de implementare poate fi urmtoarea, n care i iniializarea variabilelor contor se realizeaz
n cadrul expresiei expresie1.
int lmic, lmare, lcif, altcar;
for(lmare=0, lmic=0, lcif=0, altcar=0; c!='@'; ){
7
CAPITOLUL 3
// corp identic
}
//corp do-while
} while (c!='@');
cout<<"Ai introdus \n";
//. . .
2. S se calculeze suma i produsul primelor n numere naturale, n fiind introdus de la tastatur. Se vor
exemplifica modalitile de implementare cu ajutorul instruciunilor do-while, while, i for. (Se
n
observ c: S =
k
k 1
,P=
k
k 1
).
// varianta2
// varianta3
for (int S=0, P=1, k=1; k<=n; k++){
S+=k; P*=k;
}
cout<<"P="<<P<<"\tS="<<cout<<S<<'\n';
// varianta4
for (int S=0, P=1, k=1; k<=n; S+=k, P*=k, k++)
;
cout<<"P="<<P<<"\tS="<<cout<<S<<'\n';
Se presupune c primul element din irul de numere are valoarea maxim. Se memoreaz valoarea sa n variabila max. Se parcurge apo
CAPITOLUL 3
4. S se afieze literele mari ale alfabetului i codurile aferente acestora n ordine cresctoare, iar literele
mici i codurile aferente n ordine descresctoare. Afiarea se va face cu pauz dup fiecare ecran.
#include <iostream.h>
#include <conio.h>
#define DIM_PAG 22
//dimensiunea paginii (numarul de randuri de pe o pagina)
void main()
{clrscr();
cout<<"LITERELE MARI:\n";int nr_lin=0; // nr_lin este contorul de linii de pe un ecran
for (char LitMare='A'; LitMare<='Z'; LitMare++){
if (nr_lin==DIM_PAG){
cout<<"Apasa o tasta...."; getch(); clrscr(); nr_lin=0;}
cout<<"Litera "<<LitMare<<" cu codul ASCII "<<(int)LitMare<<'\n';
5. S se scrie un program care realizeaz conversia numrului N ntreg, din baza 10 ntr-o alt baz de
numeraie, b<10 (N i b citite de la tastatur). Conversia unui numr ntreg din baza 10 n baza b se
realizeaz prin mpriri succesive la b i memorarea resturilor, n ordine invers. De exemplu:
547:8=68 rest 3; 68:8=8 rest 4; 8:8=1 rest 0; 1:8=0 rest 1
547 10 = 1043 8
#include <iostream.h>
void main()
{ int nrcif=0,N,b,rest,Nv,p=1;
long Nnou=0;
cout<<"\nIntroduceti baza<10, b=";cin>>b;
cout<<"Introduceti numarul in baza 10, nr=";cin>>N;
Nv=N;
while(N!=0)
{
rest=N%b;
N/=b;
cout<<"nr="<<N<<'\n'; cout<<"rest="<<rest<<'\n';
nrcif++; Nnou+=rest*p;
p*=10;
cout<<"Nr. nou="<<Nnou<<'\n';
}
cout<<"Numarul de cifre este "<<nrcif<<'\n'; cout<<"Nr. in baza 10 "<<Nv;
cout<<" convertit in baza "<<b<<" este "<<Nnou<<'\n'; }
xk
6. S se calculeze seria urmtoare cu o eroare mai mic dect EPS (EPS introdus de la tastatur): 1+ k 1 k
, x [0,1], x citit de la tastatur. Vom aduna la sum nc un termen ct timp diferena dintre suma
calculat la pasul curent i cea calculat la pasul anterior este mai mare sau egal cu EPS.
#include <iostream.h>
#include <conio.h>
#include <math.h>
void main()
{ double T,S,S1;long k;k=1;T=1;S=T;double x; cout<<"x="; cin>>x;
// T= termenul general de la pasul curent; S=suma la pasul curent; S1=suma la pasul anterior
9
CAPITOLUL 3
do {
S1=S;k=k+1;T=pow(x,k)/k;
//funcia pow(x, k), aflat n <math.h> calculeaz x
S=S+T; // cout<<k<<" "<<T<<" "<<S<<'\n';getch();
} while ((S-S1)>=EPS);
cout<<"Nr termeni="<<k<<" T="<<T<<"
S="<<S<<'\n';
}
Instruciunea break
Aa cum se observ din figura 3.4., utilizat n cadrul instruciunilor ciclice, instruciunea break "foreaz"
ieirea din acestea. Fr a se mai testa valoarea expresiei (condiia) care determin repetarea corpului
instruciunii ciclice, se continu execuia cu instructiunea care urmeaz instructiunii ciclice. Astfel, se
ntrerupe repetarea corpului instruciunii ciclice, indiferent de valoarea condiiei de test.
Utilizarea n cadrul instruciunii switch: n situaia n care s-a ajuns la o valoare a unei expresiei constante
egal cu cea a expresiei aritmetice, se execut instruciunea corespunztoare acelei ramuri. Dac se ntlnete
instruciunea break, parcurgerea este ntrerupt (nu se mai compar valoarea expresiei aritmetice cu
urmtoarele constante), deci se va trece la execuia primei instruciuni de dup switch. Dac nu este ntlnit
break, parcurgerea continu. Instruciunea breakl cauzeaz deci, ieirea imediat din switch.
Instruciunea continue
ntlnirea instruciunii continue (figura 3.4.) determin ignorarea instruciunilor care o urmeaz n corpul
instruciunii ciclice i reluarea execuiei cu testarea valorii expresiei care determin repetarea sau nu a
corpului ciclului.
Exemplu: S revenim la programul realizat pentru problema 1, care folosete instruciunea dowhile. Dac
primul caracter citit este chiar caracterul @, se realizeaz testarea acestuia; ca urmare, se afieaz mesajul
"Alt car.!" i se incrementeaz valoarea contorului altcar. Dac nu se dorete ca acest caracter s fie
testat i numrat, n corpul instruciunii do while putem face un test suplimentar.
int lmic=0,lmare=0,lcif=0,altcar=0;cout<<"Atept caract.:";cin>>c;
do {
if (c == '@')
break;
//ieire din do while
//corp do-while
while (expresie1){
instructiune1;
do{
instructiune2;
instructiune1;
if
(expresie2)
for (expr1;
expr2; expr3)){
instructiune2;
break; 1;
instructiune
if (expresie2)
else
instructiune2;
break;
continue;
if (expresie2)
else
instructiune3;
break;
continue;
}
else
instructiune3;
continue;
} while (expresie1);
instructiune3;
} while (c!='@');
cout<<"Ai introdus \n";
//. . .
10
CAPITOLUL 3
NTREBRI I EXERCIII
Chestiuni teoretice
Chestiuni practice
1.
2.
3.
4.
(n<0)
if (n>=90)
if (x!=0)
int b= n/x;
6. S se citeasc un numar natural n. S se scrie un program care afieaz dac numrul n citit reprezint
sau nu, un an bisect (anii biseci sunt multipli de 4, exceptnd multiplii de 100, dar incluznd multiplii de
400).
7. S se gseasc toate numerele de dou cifre care satisfac relaia:
8. S se citeasc un ir de
numere reale, pn la ntlnirea numarului 800 i s se
2
afieze valoarea minim xy ( x y )
introdus, suma i produsul elementelor irului.
9. Scriei un program care
s verifice inegalitatea 1/(n+1) < ln[(n+1)/n] < 1/n, unde n
este un numr natural pozitiv, introdus de la tastatur.
10. Fie funcia
x 3
e
, x [0, 1)
S se calculeze f(x), x citit de la tastatur.
f(x)= sinx+cosx
, x [1, 2)
0,9ln(x+3)
, x [2, 100]
11. S se scrie un program care calculeaz i afieaz maximul a 3 numere reale (a, b i c) citite de la
tastatur.
12. S se scrie un program care calculeaz i afieaz minimul a 3 numere reale (a, b i c) citite de la
tastatur.
13. S se citeasc 2 caractere care reprezint 2 litere mari. S se afieze caracterele citite n ordine alfabetic.
14. S se citeasc 3 caractere care reprezint 3 litere mici. S se afieze caracterele citite n ordine alfabetic.
15. S se scrie un program care citete o cifr. n funcie de valoarea ei, s se fac urmtorul calcul: dac
cifra este 3, 5 sau 7 s se afieze ptratul valorii numerice a cifrei; dac cifra este 2, 4 sau 6 s se afieze
cubul valorii numerice a cifrei; dac cifra este 0 sau 1 s se afieze mesajul "Valori mici"; altfel., s se
afieze mesajul "Caz ignorat!".
16. Fie irul lui Fibonacci, definit astfel:
f(0)=0, f(1)=1, f(n)=f(n-1)+f(n-2) n cazul n care n>1.
S se scrie un program care implementeaz algoritmul de calcul al irului Fibonacci.
17. S se calculeze valoarea polinomului Cebev de ordin n ntr-un punct x dat, cunoscnd relaia:
11
CAPITOLUL 3
1 + x /3 - x /5 + x /7 -
cu o eroare mai mic dect epsilon (epsilon citit de la tastatur). S se afieze i numrul de termeni ai
sumei.
23. S se citeasc un numr ntreg format din 4 cifre (abcd). S se calculeze i s se afieze valoarea
expresiei reale:
4*a + b/20 -c + 1/d.
24. S se scrie un program care afieaz literele mari ale alfabetului n ordine cresctoare, iar literele mici n ordine descresctoare.
25. S se scrie un program care genereaz toate numerele perfecte pn la o limit dat, LIM. Un numr
perfect este egal cu suma divizorilor lui, inclusiv 1 (exemplu: 6=1+2+3).
26. S se calculeze valoarea sumei urmatoare, cu o eroare EPS mai mic de 0.0001:
S=1+(x+1)/ 2! + (x+2)/ 3! + (x+3)/ 3! + ...
, unde 0<=x<=1, x citit de la tastatur.
27. S se genereze toate numerele naturale de 3 cifre pentru care cifra sutelor este egal cu suma cifrelor
zecilor i unitilor.
28. S se citeasc cte un numr ntreg, pn la ntlnirea numrului 90. Pentru fiecare numar s se afieze
un mesaj care indic dac numrul este pozitiv sau negativ. S se afieze cel mai mic numr din ir.
29. S se genereze toate numerele naturale de 3 cifre pentru care cifra zecilor este egal cu diferena cifrelor
sutelor i unitilor.
30. S se calculeze suma:
(1 + 2!) / (2 + 3!) - (2+3!) / (3+4!) + (3+4!) / (4+5!) - .....
12