Limbajele moderne sunt alcatuite pe principiile programarii structurate. Conform lui C. Bohm si G. Jacobini, orice algoritm poate fi realizat prin combinarea a trei structuri fundamentale:
IMPLEMENTAREA STRUCTURII SECVENTIALE
Structura secventiala este o insiruire de secvente de prelucrare (instructiuni), plasate una dupa alta, in ordinea in care se doreste executia acestora.
Reprezentarea structurii secventiale cu ajutorul pseudocodului:
Implementarea structurii secventiale se realizeaza cu ajutorul instructiunilor:instr1;
instr2;
. . . . .
Exemple:
int a;
. . . . . .
int j;
;
for (;;)
{
. . . .
}
Instructiunea expresie
Sintaxa:
expresie;
sau:
apel_functie;
Exemple:
int b, a=9;
double c;
b=a+9;
cout<<a;
c=sqrt(a);
clrcsr();//apelul functiei predefinite care sterge ecranul; prototipul
in headerul conio.h
Instructiunea compusa (instructiunea bloc)
Sintaxa: {
declaratii;
instr1;
instr2;
. . . .
}
Intr-un bloc se pot declara si variabile care pot fi accesate doar
in corpul blocului. Instructiunea bloc este utilizata in locurile in care
este necesara prezenta unei singure instructiuni, insa procesul de calcul
este mai complex, deci trebuie descris in mai multe secvente.
IMPLEMENTAREA STRUCTURII DE DECIZIE (ALTERNATIVE, DE SELECTIE)
Reprezentarea prin schema logica si prin pseudocod a structurilor de decizie si repetitive sunt descrise in capitolul 1. Se vor prezenta in continure doar instructiunile care le implementeaza.
Instructiunea if:
Sintaxa:
if (expresie)
instructiune1;
[ else
instructiune2; ]
Ramura else este optionala.
La intalnirea instructiunii if, se evalueaza expresie (care reprezinta
o conditie) din paranteze. Daca valoarea expresiei este 1, sau diferita de 0 (conditia este
indeplinita) se executa instructiune1; daca valoarea expresiei este 0 (conditia
nu este indeplinita), se executa instructiune2. Deci, la un moment dat,
se executa doar una dintre cele doua instructiuni: fie instructiune1, fie
instructiune2. Dupa executia instructiunii if se trece la executia instructiunii
care urmeaza acesteia.
Observatii:
1. Instructiune1 si instructiune2 pot fi instructiuni compuse (blocuri),
sau chiar alte instructiuni if (if-uri imbricate).
2. Deoarece instructiunea if testeaza valoarea numerica a expresiei
(conditiei), este posibila prescurtarea: if (expresie), in loc de if (expresie
!= 0).
3. Deoarece ramura else a instructiunii if este optionala, in cazul
in care aceasta este omisa din secventele if-else imbricate, se produce
o ambiguitate. De obicei, ramura else se asociaza ultimei instructiuni
if.
Exemplu:
if (n>0)
if (a>b)
z=a;
else z=b;
4. Pentru claritatea programelor sursa se recomanda alinierea instructiunilor
prin utilizarea tabulatorului orizontal.
5. Deseori, apare constructia:
if (expresie1)
instructiune1;
else
if (expresie2)
instructiune2;
else
if (expresie3)
instructiune3;
. . . . . . . . .
else
instructiune_n;
Aceeasi constructie poate fi scrisa si astfel:
if (expresie1)
instructiune1;
else if (expresie2)
instructiune2;
else if (expresie3)
instructiune3;
. . . . .. . . . . .
else
instructiune_n;
Expresiile sunt evaluate in ordine; daca una dintre expresii are valoarea
1, se executa instructiunea corespunzatoare si se termina intreaga inlantuire.
Ultima parte a lui else furnizeaza cazul cand nici una dintre expresiile
1,2,. . ., n-1 nu are valoarea 1.
6. In cazul in care instructiunile din cadrul if-else sunt simple,
se poate folosi operatorul conditional.
Exercitii:
1. Sa se citeasca de la tastatura un numar real. Daca acesta se afla
in intervalul [-1000, 1000], sa se afiseze 1, daca nu, sa se afiseze -1.
#include <iostream.h>
int 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; */
return 0;
}
Uneori, constructia if-else este utilizata pentru a compara valoarea unei variabile cu diferite valori constante, ca in programul urmator:
2. Se citeste un caracter reprezentand un operator aritmetic binar simplu.
In functie de caracterul citit, se afiseaza numele operatiei pe care acesta
o poate realiza.
#include <iostream.h>
int 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”;
return 0;
}
Instructiunea switch
In unele cazuri este necesara o decizie multipla speciala. Instructiunea
switch permite acest lucru.
Reprezentare prin pseudocod:
Daca expresie=expr_const_1
instructiune1;
[iesire;]
Altfel daca expresie=expr_const_2
instructiune2;
[iesire;]
............................................
Altfel daca expresie=expr_const_n-1
instructiune_n-1;
[iesire;]
Altfel instructiune_n;
Se testeaza daca valoarea pentru expresie este una dintre constantele
specificate (expr_const_1, expr_const_2, etc.) si se executa instructiunea
de pe ramura corespunzatoare. In schema logica test_expresie este una din
conditiile: expresie=expr_const_1, expresie=expr_const_2, etc.
Sintaxa:
switch (expresie)
{
case expresie_const_1: instructiune_1;
[break;]
case expresie_const_2: instructiune_2;
[break;]
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
case expresie_const_n-1: instructiune_n-1;
[break;]
[ default: instructiune_n; ]
}
Este evaluata expresie (expresie aritmetica), iar
valoarea ei este comparata cu valoarea expresiilor constante 1, 2, etc.
(expresii constante=expresii care nu contin variabile). In situatia in
care valoarea expresie este egala cu valoarea expr_const_k, se executa
instructiunea corespunzatoare acelei ramuri (instructiune_k). Daca se intalneste
instructiunea break, parcurgerea este intrerupta, deci se va trece la executia
primei instructiuni de dupa switch. Daca nu este intalnita instructiunea
break, parcurgerea continua. Break-ul cauzeaza deci, iesirea imediata din
switch.
In cazul in care valoarea expresiei nu este gasita
printre valorile expresiilor constante, se executa cazul marcat cu eticheta
default (cand acesta exista). Expresiile expresie, expresie_const_1, expresie_const_2,etc.,
trebuie sa fie intregi. In exemplul urmator, ele sunt de tip char, dar
o data de tip char este convertita automat in tipul int.
Exercitiu: Sa rescriem programul pentru problema 2, utilizand instructiunea switch.
#include <iostream.h>
int 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”;
}
return 0;
}
IMPLEMENTAREA STRUCTURILOR REPETITIVE (CICLICE)
Exista doua categorii de instructiuni ciclice: cu test initial si cu test final.
Implementarea structurilor ciclice cu test initial
Structura ciclica cu test initial este implementata prin instructiunile
while si for.
Instructiunea while
Sintaxa:
while (expresie)
instructiune;
La intalnirea acestei instructiuni, se evalueaza expresie. Daca aceasta are valoarea 1 - sau diferita de 0 - (conditie indeplinita), se executa instructiune. Se revine apoi in punctul in care se evalueaza din nou valoarea expresiei. Daca ea este tot 1, se repeta instructiune, s.a.m.d. Astfel, instructiunea (corpul ciclului) se repeta atat timp cat expresie are valoarea 1. In momentul in care expresie ia valoarea 0 (conditie neindeplinita), se iese din ciclu si se trece la urmatoarea instructiune de dupa while.
Observatii:
1. In cazul in care la prima evaluare a expresiei, aceasta are valoarea
zero, corpul instructiunii while nu va fi executat niciodata.
2. Instructiune din corpul ciclului while poate fi compusa (un bloc),
sau o alta instructiune ciclica.
3. Este de dorit ca instructiunea din corpul ciclului while sa modifice
valoarea expresiei. Daca nu se realizeaza acest lucru, corpul instructiunii
while se repeta de un numar infinit de ori.
Exemplu:
int a=7;
while (a==7)
cout<<”Buna ziua!\n”; // ciclu infinit; se repeta la infinit
afisarea mesajului
Instructiunea for
In majoritatea limbajelor de programare de nivel inalt, instructiunea
for implementeaza structura ciclica cu numar cunoscut de pasi . In limbajul
C instructiunea for poate fi utilizata intr-un mod mult mai flexibil.
Reprezentare in pseudocod:
evaluare expresie1
CAT TIMP expresie2 REPETA
INCEPUT
instructiune
evaluare expresie3
SFARSIT
Sintaxa:
for (expresie1; expresie2; expresie3)
instructiune;
Nu este obligatorie prezenta expresiilor, ci doar a instructiunilor
vide.
for ( ; expresie2; )
sau:
for ( ; ; )
instructiune;
instructiune;
Implementarea structurilor ciclice cu test final
Instructiunea do-while
Sintaxa:
do instructiune;
while(expresie);
Se executa instructiune. Se evalueaza apoi expresie. Daca aceasta are valoarea 1, se executa instructiune. Se testeaza din nou valoarea expresiei. Se repeta instructiune cat timp valoarea expresiei este 1 (conditia este indeplinita). In cazul instructiunii do-while, corpul ciclului se executa cel putin o data.
Exercitii:
1. Se citeste cate un caracter, pana la intalnirea caracterului @.
Pentru fiecare caracter citit, sa se afiseze un mesaj care sa indice daca
s-a citit o litera mare, o litera mica, o cifra sau un alt caracter. Sa
se afiseze cate litere mari au fost introduse, cate litere mici, cate cifre
si cate alte caractere. Se prezinta trei modalitati de implementare (cu
instructiunea while, cu instructiunea for si cu instructiunea do-while).
#include <iostream.h>
#include <conio.h>
int main()
{ char c;
int lmic=0, lmare=0, lcif=0;
int altcar=0;
cout<<"Astept car.:"; cin>>c;
while (c!='@'){
if (c>='A' && c<='Z') {
cout<<"Lit. mare!\n";
lmare++; }
else if (c>='a' && c<='z') {
cout<<"Lit. mica!\n";
lmica++; }
else if (c>='0' && c<='9') {
cout<<"Cifra!\n";
lcif++; }
else {
cout<<"Alt car.!\n";
altcar++; }
cout<<"Astept car.:";cin>>c;
}
cout<<"Ati introdus \n";
cout<<lmare<<" litere mari, ";
cout<<lmic<<" litere mici\n";
cout<<lcif<<" cifre si \n";
int lmic=0, lmare=0, lcif=0;
int altcar=0;
cout<<"Astept caract.:";cin>>c;
do {
//corp do-while
} while (c!='@');
cout<<"Ati introdus \n";
//. . .
Sa se calculeze suma si produsul primelor n numere naturale, n fiind introdus de la tastatura. Se vor exemplifica modalitatile de implementare cu ajutorul instructiunilor do-while, while, si for.
cout<<"n="; int n; cin>>n;
int S=0, P=1, k=1;
while (k <= n){
S+=k; P*=k;
k++;
}
cout<<"P="<<P<<"\tS="<<S<<'\n';
cout<<"n="; int n; cin>>n;
int S=0, P=1, k=1;
do{
S+=k; P*=k;
k++;
} while (k <= n);
cout<<"P="<<P<<"\tS="<<S<<'\n';
int S=0, P=1, k;
for (k=1; k<=n; k++){
S+=k; P*=k;
}
cout<<"P="<<P<<"\tS=";
cout<<S<<'\n';
FACILITATI DE INTRERUPERE A UNEI SECVENTE
Pentru o mai mare flexibilitate (tratarea exceptiilor care pot apare in procesul de prelucrare), in limbajul C se utilizeaza instructiunile break si continue. Ambele instructiuni sunt utilizate in instructiunile ciclice. In plus, instructiunea break poate fi folosita in instructiunea switch.
Instructiunea break
Este utilizata in cadrul instructiunilor ciclice, instructiunea break
"forteaza" iesirea din acestea. Fara a se mai testa valoarea expresiei
(conditia) care determina repetarea corpului instructiunii ciclice, se
continua executia cu instructiunea care urmeaza instructiunii ciclice.
Astfel, se intrerupe repetarea corpului instructiunii ciclice, indiferent
de valoarea conditiei de test.
Utilizarea in cadrul instructiunii switch: In situatia in care s-a
ajuns la o valoare a unei expresiei constante egala cu cea a expresiei
aritmetice, se executa instructiunea corespunzatoare acelei ramuri. Daca
se intalneste instructiunea break, parcurgerea este intrerupta (nu se mai
compara valoarea expresiei aritmetice cu urmatoarele constante), deci se
va trece la executia primei instructiuni de dupa switch. Daca nu este intalnit
break, parcurgerea continua. Instructiunea breakl cauzeaza deci, iesirea
imediata din switch.
Instructiunea continue
Intalnirea instructiunii continue determina ignorarea instructiunilor
care o urmeaza in corpul instructiunii ciclice si reluarea executiei cu
testarea valorii expresiei care determina repetarea sau nu a corpului ciclului.