Documente Academic
Documente Profesional
Documente Cultură
Instruciunea expresie
Instruciunea compus - bloc
Instruciunea if
Instruciunea switch
Instruciunea while
Instruciunea for
Instruciunea do
Instruciunea break i continue
Terminarea programului: exit i return
Anexa A: Sfaturi practice pentru devoltarea programelor C. Depanare
Anexa B: Programele din cursul 1 rezolvate n C
Introducere
Dup cum spuneam, exist trei tipuri de construcii de baz pentru controlul
fluxului operaiilor: secvena, decizia (condiia) i iteraia (bucla, ciclu, repetiia), aa cum
sunt ilustrate mai jos.
Operaie 1
DA
NU
Operaie 2
Bucla
.
.
.
DA
Operaie n
NU
Secvena
Decizia
Iteraia
Instruciunea expresie
O expresie urmat de caracterul terminator de instruciune ; devine o instruciune
expresie.
Sintaxa:
expresie;
Cele mai importante cazuri de instruciuni expresie sunt:
Tip instruciune expresie Descriere
Instruciunea vid
conine doar terminatorul ;
este folosit pentru a marca
absena unei prelucrri ntr-o alt
instruciune (if, while, etc)
Instruciunea de apelare un apel de funcie terminat cu ;
a unei funcii
Instruciunea de atribuire
Exemple
for (i=0; i<10000; i++) ;
/* temporizare, de
10000 de ori nu fac nimic
*/
getchar();
r=sqrt(a);
system(pause);
o expresie de atribuire terminat cu a=1;
;
++a;
c=r/(a+b);
i=j=k=1;
// schimba a i b prin t
//Blocul:
{
a++;
c=a+ --b;
printf("%d\n",c);
}
// este echivalent cu instructiunea expresie:
a++, c=a+ --b, printf("%d\n",c);
Semantica:
Se evalueaz expresie; dac valoarea ei este adevrat (diferit de 0) se execut
instruciune1, altfel, dac exist ramura else, se execut instruciune2.
Observaii:
Instruciunea corespunde structurii de control decizie din schemele logice;
Pentru ca programele scrise s fie ct mai clare este bine ca instruciunile
corespunztoare lui if si else sunt de obicei scrise pe liniile urmtoare i sunt
deplasate spre dreapta, pentru a pune n evident structurile i modul de asociere
ntre if i else. Acest mod de scriere permite citirea corect a unor cascade de decizii.
Valoarea expresiei dintre paranteze se compar cu zero, iar instruciunea care
urmeaz se va executa numai atunci cnd expresia are o valoare nenul. n general
expresia din instruciunea if reprezint o condiie, care poate fi adevrat (valoare
nenul) sau fals (valoare nul). De obicei expresia este o expresie de relaie (o
comparaie de valori numerice) sau o expresie logic care combin mai multe relaii
ntr-o condiie compus dar poate fi orice expresie cu rezultat numeric.
Instruciunea corespunztoare valorii adevrat sau fals, poate fi orice instruciune C:
o instruciune expresie terminat cu simbolul ;
o instruciunea bloc ( atunci cnd trebuie executate mai multe prelucrri )
o alta instruciune de decizie - deci instruciunile if-else pot fi ncuibate; fiecare
else corespunde if-ului anterior cel mai apropiat, fr pereche.
O problem de interpretare poate apare n cazul a dou (sau mai multe) instruciuni
if incluse, dintre care unele au alternativa else, iar altele nu conin pe else. Regula de
interpretare este aceea c else este asociat cu cel mai apropiat if fr else (dinaintea
lui).
O sintez a celor trei moduri de utilizare a lui if precum i fluxul de operaii n schem logic
sunt date n cele ce urmeaz:
Sintax
Flux operaii
// if-then
if ( expresie ) {
bloc_DA;
}
expresie
NU
DA
bloc DA
DA
// if-then-else
if ( expresie )
bloc_DA ;
else
bloc_NU ;
// if incuibat
if (expresie_1 )
bloc_1 ;
else
if (expresie_2 )
bloc_2 ;
else
if (expresie_3 )
bloc_3 ;
else
if (expresie_4 )
......
else
bloc_Else ;
NU
expresie
bloc NU
bloc DA
DA
Expresie1
NU
Expresie2
bloc 1
NU
DA
bloc 2
bloc Else
// if incuibat
if (expresie_1 )
bloc_1 ;
else
if (expresie_2 )
bloc_2 ;
else
if (expresie_3 )
bloc_3 ;
else
if (expresie_4 )
......
else
bloc_Else ;
Exemple
if (nota >= 5) {
printf("Congratulation!\n");
printf("Keep it up!\n");
}
if (nota >= 5) {
printf("Congratulation!\n");
printf("Keep it up!\n");
} else
printf("Try Harder!\n");
Exemple:
/* urmatoarele trei secvente echivalente verifica daca trei valori pot
reprezenta lungimile laturilor unui triunghi */
if(a<b+c && b<a+c && c<a+b)
puts("pot fi laturile unui triunghi");
else
puts("nu pot fi laturile unui triunghi");
if(a<b+c && b<a+c && c<a+b)
;
//pentru cond adevarata nu se executa nimic: apare instructiunea vida
else
printf("nu ");
puts("pot fi laturile unui triunghi");
if(!(a<b+c && b<a+c && c<a+b)) // sau if(a>=b+c || b>=a+c || c>=a+b)
printf("nu ");
puts("pot fi laturile unui triunghi");
prelucrare_1
break;
prelucrare_2
break;
prelucrare_n
break;
prelucrare_x ;
}
O sintez a celor dou moduri de utilizare a lui switch precum i fluxul de operaii n schem
logic este dat n cele ce urmeaz:
Sintax
// switch-case
switch (expresie) {
case c1:
prelucrare_1
case c2:
prelucrare_2
case cn:
prelucrare_n
default:
prelucrare_x
}
Flux operaii
c1?
DA
prel_1
NU
c2?
DA
prel_2
NU
default
// switch-case
switch (expresie) {
case c1:
prelucrare_1
break;
case c2:
prelucrare_2
break;
case cn:
prelucrare_n
break;
default:
prelucrare_x
}
c1?
DA
break
prel_1
NU
c2?
DA
prel_2
break
NU
default
Exemple
//calculeaza rezulatul expresiei num1 oper num2
char oper; int num1, num2, result;
......
switch (oper) {
case '+':
result = num1 + num2; break;
case '-':
result = num1 - num2; break;
case '*':
result = num1 * num2; break;
case '/':
result = num1 / num2; break;
default:
printf("Operator necunoscut");
}
// determina nr de zile dintr-o lun a unui an nebisect
switch (luna) {
// februarie
case 2: zile=28; break;
// aprilie, iunie,..., noiembrie
case 4: case 6: case 9: case 11: zile =30; break;
// ianuarie, martie, mai,.. decembrie, celelalte (1,3,5,..)
default: zile=31;
}
Instruciuni repetitive
Exist trei tipuri de instruciuni de ciclare (bucle, iteraii): while, for i do-while.
Instruciunea while
Instruciunea while exprim structura de ciclu cu condiie iniial i cu numr necunoscut de
pai i are forma urmtoare:
Sintaxa:
while (expresie)
instructiune
Semantica
Se evalueaz expresie; dac valoarea ei este adevrat (diferit de 0 ) se execut instructiune,
dup care se evalueaz din nou expresie; daca valoarea este 0, se trece la instruciunea
urmtoare. Efectul este acela de executare repetat a instruciunii coninute n
instruciunea while ct timp expresia din paranteze are o valoare nenul (este adevrat).
Este posibil ca numrul de repetri s fie zero dac expresia are valoarea zero de la nceput.
Observatii:
Instruciunea while corespunde structurii repetitive cu test iniial de la schemele
logice;
n general expresie conine variabile care se modific n instructiune, astfel nct
expresie s devin fals, deci ciclarea s nu se fac la infinit;
n unele programe se poate s apar
while(1)
instructiune
Atunci, corpul ciclului poate s conin o instruciune de ieire din ciclu, altfel
tastarea Ctrl/Break ntrerupe programul;
urmtoarele dou instruciuni de ciclare sunt derivate din cea cu test iniial;
Ca i n cazul altor instruciuni de control, este posibil s se repete nu doar o
instruciune ci un bloc de instruciuni;
Exemple:
// cmmdc prin incercari succesive de posibili divizori, presupunem a>b
d = b;
while ( a%d || b%d )
d = d -1;
}
n exemplul anterior, dac a=8 i b=4 atunci rezultatul este d=4 i nu se execut niciodat
instruciunea din ciclu (d=d-1).
// determinare cmmdc prin algoritmul lui Euclid. While cu instructiune bloc
while (a%b > 0) {
r = a % b;
a = b;
b = r;
}// la ieirea din ciclu b este cmmdc
Expresia din instruciunea while poate s conin atribuiri sau apeluri de funcii care se fac
nainte de a evalua rezultatul expresiei:
Instruciunea for
Instruciunea for din C permite exprimarea compact a ciclurilor cu condiie iniial sau a
ciclurilor cu numr cunoscut de pai i are forma:
Sintaxa:
for (expresie1; expresie2; expresie3)
instructiune
Semantica:
Se evalueaz expresie1 care are rol de iniializare; se evalueaz apoi expresie2, cu rol de
condiie - dac valoarea ei este adevrat (diferit de 0) se execut instructiune - corpul
ciclului, dup care se evalueaz expresie3, cu rol de actualizare, apoi se evalueaz din nou
expresie2; dac valoarea este 0, se trece la instruciunea urmtoare. Cu alte cuvinte,
instructiune se execut atta timp ct expresie2 este adevrat, deci de 0 sau mai multe ori.
Efectul acestei instruciuni este echivalent cu al secvenei urmtoare:
expresie1;
while (expresie2) {
instruciune;
expresie3;
}
// operaii de iniializare
// cat timp exp2 !=0 repeta
// instruciunea repetata
// o instruciune expresie
Observaii:
Instructiunea for permite o scriere mult mai compact dect celelalte dou
instruciuni de ciclare, fiind foarte des utilizat n scrierea programelor;
Oricare din cele trei expresii poate lipsi, dar separatorul ; rmne. Absena expresie2
echivaleaz cu condiia adevrat, deci 1; in tabelul de mai jos sunt date echivalenele
cu instruciunea while, pentru cazuri cnd expresii din sintaxa for lipsesc:
for
for(;expresie;)
instructiune
for(;;)
instructiune
while
while(expresie)
instructiune
while(1)
instructiune
Cele trei expresii din instruciunea for sunt separate prin ';' deoarece o expresie
poate conine operatorul virgul. Este posibil ca prima sau ultima expresie s
reuneasc mai multe expresii separate prin virgule;
Este posibil mutarea unor instruciuni din ciclu n paranteza instruciunii for, ca
expresii, i invers - mutarea unor operaii repetate n afara parantezei.
nf = nf * k;
Instruciunea do
Instruciunea do-while se folosete pentru exprimarea ciclurilor cu condiie final, cicluri
care se repet cel puin o dat. Forma uzual a instruciunii do este urmtoarea:
Sintaxa:
do
instructiune
while ( expresie ) ;
Semantica:
Se execut instruciune - corpul ciclului, apoi se evalueaz expresie care are rol de condiie dac valoarea ei este adevrat (diferit de 0) se execut instruciune, dup care se evalueaz
din nou expresie; dac valoarea este 0, se trece la instruciunea urmtoare.
Cu alte cuvinte, instruciune se execut atta timp ct expresie este adevrat; ca
observaie, instruciune se execut cel puin o dat.
Observaii:
Instruciunea echivaleaz cu structura repetitiv cu test final de la scheme logice;
Un ciclu do tipic apare la citirea cu validare a unei valori, citire repetat pn la introducerea
corect a valorii respective:
do {
printf ("n (<1000): "); // n trebuie sa fie sub 1000
scanf("%d", &n);
if ( n <=0 || n>=1000)
printf ( Eroare la valoarea lui n ! \n);
} while (n>1000) ;
// for
Flux operaii
Expresie1
Expresie3
Bucla
Expresie2
NU
DA
Instruciune
// while-do
while ( expresie )
instruciune
Bucla
Expresie
DA
Instruciune
NU
// do-while
Instruciune
do {
instruciune
}
while ( expresie ) ;
Bucla
Expresie
DA
NU
Exemple scrise utiliznd cele trei instruciuni repetitive:
1. Suma primelor 1000 de numere naturale
2. Secvene echivalente care citesc cu validare o variabil - n urma citirii, variabila ntreag
trebuie s aparin intervalului [inf,sup]:
Instruciune
Exemple
// Suma de la 1 la 1000
int suma = 0;
for (int nr = 1; nr <= 1000; ++nr) {
suma += nr;
}
for
puts(Valoare), scanf("%d",&var));
// Citire cu validare in intervalul [inf, sup]
for( ;puts(Valoare), scanf("%d",&var), var<inf || var>sup;);
// Suma de la 1 la 1000
int suma = 0, nr = 1;
while (nr <= 1000) {
suma += nr;
++nr;
}
while
do while
// Suma de la 1 la 1000
int suma = 0, nr = 1;
do {
suma += nr;
++nr;
} while (nr <= 1000);
// Citire cu validare in intervalul [inf, sup]
do{
puts(Valoare);
scanf("%d",&var);
}while( var<inf || var>sup);
Un ciclu din care se poate iei dup un numr cunoscut de pai sau la ndeplinirea
unei condiii (ieire forat) este de obicei urmat de o instruciune if care stabilete
cum s-a ieit din ciclu: fie dup numrul maxim de pai, fie mai nainte datorit
satisfacerii condiiei.
Exemplu:
// verifica daca un numar dat n este prim
for (k=2; k<n;k++)
if ( n%k==0) break;
//daca gasim un divizor, iesim, n nu este prim!
if (k==n) printf ("prim \n"); /*s-a iesit normal din ciclu-nu are
divizor*/
else printf ("neprim \n"); /*s-a iesit fortat prin break - are divizor */
Utilizarea instruciunii break poate simplifica expresiile din while sau for i poate
contribui la urmrirea mai uoar a programelor, dei putem evita instruciunea
break prin complicarea expresiei testate n for sau while. Secvenele urmtoare sunt
echivalente:
//se iese cand e este diferita de 0
for (k=0 ; k<n; k++)
if (e) break;
for (k=0 ; k<n && !e ; k++);
while ( ! corect ) {
// atata timp cat nu s-au citit date corecte
printf ( ore, minute, secunde: );
if ( scanf(%i%i%i, &h, &m, &s) !=3 ) {
//nu s-au citit 3 nr intregi
printf ( Eroare insuficiente date numerice\n);
fflush(stdin);
//stergere buffer de intrare
continue; // salt peste instructiunile urmatoare, reia citirea
}
Observaii:
Uneori se recomand s evitm utilizarea instruciunilor break i continue deoarece
programele care le folosesc sunt mai greu de citit i de neles. ntotdeauna putem scrie
acelai program fr s folosim break i continue.
Exemplu:
// Suma de la 1 la n, excluzand 11, 22, 33,...
int n = 100;
int suma = 0;
for (int nr = 1; nr <= n; nr++) {
if (nr % 11 == 0) continue; /* sare peste restul corpului buclei i
trece la urmat. iteraie nr+1 */
suma += nr;
// aici ajung doar daca nr nu e divizibil cu 11
}
// Este mai bine s rescriem bucla for astfel:
for (int nr = 1; nr <= n; nr++) {
if (nr % 11 != 0) suma += nr;
}
Terminarea programului
Un program se termin n mod normal n momentul n care s-au executat toate
instruciunile sale. Dac dorim s form terminarea lui, putem folosi funcia exit sau
instruciunea return.
Funcia exit are urmtoarea sintax:
Sintaxa:
exit();
sau:
exit(int codIesire);
Semantica:
Termin programul i returneaz controlul sistemului de operare (OS). Prin convenie,
returnarea codului 0 indic terminarea normal a programului, n timp ce o valoare diferit
de zero indic o terminare anormal.
Exemplu:
if (nrErori > 10) {
printf( "prea multe erori!\n");
exit(1);
// Terminarea programului
n continuare, gsii dou anexe, una cu sfaturi practice pentru devoltarea programelor C
(good practices) i modul de depanare a programelor C n Netbeans i CodeBlocks, iar cea
de-a doua cu programele din cursul 1 rezolvate n C:
Anexa A
Sfaturi practice pentru devoltarea programelor C. Depanare
Este important s scriem programe care produc rezultate corecte, dar de asemenea este
important s scriem programe pe care alii (i chiar noi peste cteva zile) s le putem
nelege, astfel nct s poat fi uor ntreinute. Acesta este ceea ce se numete un program
bun.
Iat cteva sugestii:
Respect conveia stabilit deja la proiectul la care lucrezi astfel nct ntreaga echip
s respecte aceleai reguli.
Formateaz codul surs cu indentare potrivit, cu spaii i linii goale. Folosete 3 sau
4 spaii pentru indentare i linii goale pentru a marca seciuni diferite de cod.
Alege nume bune i descriptive pentru variabile si funcii: coloan, linie, xMax,
numElevi. Nu folosii nume fr sens pentru variabile, cum ar fi a, b, c, d. Evitai
nume de variabile formate doar dintr-o liter (mai uor de scris dar greu de neles),
excepie fcnd nume uzuale cum ar fi coordonatele x, y, z i nume de index precum
i.
Scrie comentarii pentru bucile de cod importante i complicate. Comenteaz
propriul cod ct de mult se poate.
Scrie documentaia programului n timp ce scrii programul.
Evit construciile nestructurate, cum ar fi break i continue, deoarece sunt greu de
urmrit.
Erori n programare
Exist trei categorii de erori n progamare:
Erori de compilare (sau de sintax): pot fi reparate uor.
Erori de rulare: programul se oprete prematur fr a produce un rezultat de
asemenea se repar uor.
Erori de logic: programul produce rezultate eronate. Eroarea este uor de gsit dac
rezultatele sunt eronate mereu. Dar dac programul produce de asemenea rezultate
corecte ct i rezultate eronate cteodat, eroare este foarte greu de identficat.
Acest tip de erori devine foarte grav dac nu este detectat nainte de utilizarea
efectiv a programului n producie. Implementarea unor programe bune ajut la
mimimizarea i detectarea acestor erori. O startegie de testare bun este necesar
pentru a certifica corectitudinea programului.
Programe de depanare
Exista cteva tehinci de depanare a programaelor:
1. Uit-te mult la cod! Din pcate, erorile nu o s-i sar n ochi nici dac te uii destul
de mult.
2. Nu nchide consola de erori, cnd apar mesaje pretinznd c totul este n regul.
Analizeaz mesajele de eroare! Asta ajut de cele mai multe ori.
Anexa B
Programele din laboratorul 1 rezolvate n C