Documente Academic
Documente Profesional
Documente Cultură
Programare în limbajul C
Durata: 10 ore
133
instrucţiunile de salt. În situaţia în care sintaxa limbajului
impune utilizarea unei singure instrucţiuni, dar logica
programului cere folosirea unei secvenţe de instrucţiuni, secvenţa
de instrucţiuni se organizează ca o instrucţiune bloc (sau
instrucţiune compusă). O instrucţiune bloc începe cu { şi se
termină cu }.
Instrucţiuni expresie
Instrucţiunea expresie are forma generală:
expresie;
. . .
x=(a+b)*c;
x+=2;
p++;
getch();
Instrucţiuni de decizie
INSTRUCTIUNEA IF
Forma generală a instrucţiunii if este:
if(expresie)
instructiune_1;
else
instructiune_2;
134
Fals expresie Adevărat
instrucţiune_2 instrucţiune_1
Exemplul 5.1
Programul calculează şi afişează radicalul dintr-un număr.
#include "stdio.h"
#include "conio.h"
#include "math.h"
void main(void)
{
float x,y;
printf("\n Introduceti x=");
scanf("%f",&x);
if (x<=0)
printf("\n Calcul imposibil");
else
{
y=sqrt(x);
printf("\n y=%f",y);
}
getch();
}
Observaţii:
Sintaxa generală a instrucţiunii if cere pe ambele
alternative câte o instrucţiune. În situaţia în care pe o
alternativă sunt necesare mai multe instrucţiuni
acestea vor fi grupate cu ajutorul acoladelor într-o
instrucţiune bloc. Astfel, în exemplul de mai sus,
secvenţa
135
{
y=sqrt(x);
printf("\n y=%f",y);
}
if(expresie)
instructiune_1
else;
if(expresie)
instructiune;
Fals Adevărat
expresie
instrucţiune
136
Exemplul 5.2
Programul calculează maximul dintre două numere.
#include "stdio.h"
#include "conio.h"
void main(void)
{
float x,y,max;
printf("\n x=");
scanf("%f",&x);
printf("\n y=");
scanf("%f",&y);;
max=x;
if (max<y)
max=y;
printf("\n Maximul dintre x=%.2f si
y=%.2f este=%.2f",x,y,max);
getch();
}
if(expr1)
instr1;
else
if(expr2)
instr2;
else
. . . . . .
if(exprn)
instrn;
else
instrn+1
137
structură cu adâncime mare (mult deplasată spre dreapta). Din
acest motiv se foloseşte de obicei forma:
if(expr1)
instructiune1;
else if(expr2)
instructiune2;
else if(expr3)
instructiune3;
. . . . . .
else
instructiunen+1;
Exemplul 5.3
Programul citeşte coordonatele unui număr şi stabileşte în
ce cadran se află acesta.
#include "stdio.h"
#include "conio.h"
void main(void)
{
float x,y;
printf("\n abscisa x=");
scanf("%f",&x);
printf("\n ordonata y=");
scanf("%f",&y);
if (x>=0 && y>=0)
printf("\n Numarul apartine cadranului
I");
else if (x<0 && y>=0)
printf("\n Numarul apartine cadranului
II");
else if(x<0 && y<0)
printf("\n Numarul apartine cadranului
III");
else
printf("\n Numarul apartine cadranului
IV");
getch();
}
138
if(expr!=0)
instructiune;
este echivalentă cu
if(expr)
instructiune;
b) if(x)
if(y)
printf(”\n x si y nenuli”);
else;
else
printf(”\n x nul”);
139
c) if(x&&y)
printf(”\n x si y nenuli”);
else
if(!x)
printf(”\n x nul”);
OPERATORUL CONDIŢIONAL ? :
Operatorul condiţional ?: este un operator ternar, iar forma
sa generală este:
expr1?expr2:expr3;
140
În plus, expresia expr1 ? expr2 : expr3 va lua
valoarea expr2 sau expr3 după cum expr1 este adevărată sau
nu.
Exemplul 5.4
Programul afişează maximul dintre două numere a şi b
citite de la tastatură.
#include "stdio.h"
#include "conio.h"
void main(void)
{
int a,b;
printf("\n a=");
scanf("%i",&a);
printf("\n b=");
scanf("%i",&b);
printf("\n Maximul dintre a=%i si b=%i
este %i",a,b,a<b?b:a);
getch();
}
INSTRUCTIUNEA switch
Instrucţiunea switch permite selecţia unei alternative din
mai multe posibile într-o formă comodă şi elegantă.
Forma generală a instrucţiunii este:
switch(expresie)
{
case c1:secventa de instructiuni1;break;
case c2:secventa de instructiuni2;break;
. . . . . . . .
case cn:secventa de instructiunin;break;
default:secventa de instructiunin+1;break;
}
unde:
expresie este expresia selectoare care trebuie să fie
de tip întreg;
c1,c2,...,cn sunt constante de tip întreg distincte
între ele;
default este o etichetă opţională;
secvenţa instructiunii, pentru orice
141
i=1,...,n+1 se poate constitui sau nu într-un bloc
de instrucţiuni, poate să fie vidă sau nu;
break este o instrucţiune care permite saltul la prima
instrucţiune aflată după structura switch. Prezenţa sa
este opţională.
Efectul instrucţiunii este următorul:
Dacă există un i astfel încât expresia selectoare este
egală cu ci, se execută secvenţa instructiunik,
k>=i până la primul break întâlnit sau până la
sfârşitul instrucţiunii switch.
Dacă pentru orice i=1,...,n constantele ci sunt
diferite de expresia selectoare se execută
instructiunen+1, dacă există opţiunea default sau
se iese direct din switch, dacă aceasta lipseşte.
Exemplul 5.5
Programul citeşte una din literele a,A,m,M,p,P de la
tastatură şi afişează o listă de nume care încep cu una din aceste
litere, fără să ţină cont dacă litera este mare sau mică. Dacă se
tastează alt caracter se afişează un mesaj de eroare.
#include "stdio.h"
#include "conio.h"
void main(void)
{
printf("\n Tastati una din literele:
a,A,m,M,p,P ");
switch(getch())
{
case 'a':
case 'A':printf("\n Aurel,Ana,Andrei");
break;
case 'm':
case 'M':printf("\n Maria,Mihai,Marin");
break;
case 'p':
case 'P':printf("\n Paula,Petre,Pavel");
break;
default:printf("\n Ati tastat gresit !");
}
getch();
}
142
Observaţie. În programul de mai sus, indiferent dacă s-a
tastat a sau A se afişează aceeaşi listă de nume: Aurel, Ana,
Andrei. Explicaţia este următoarea. Dacă se tastează a se
“intră“ în switch, prin case 'a'. Secvenţa de prelucrări
corespunzătoare fiind vidă şi neântâlnindu-se nici o instrucţiune
break se trece şi se execută secvenţa de prelucrări
corespunzătoare constantei case 'A' (adică afişarea listei).
Deoarece secvenţa se încheie cu break se “iese“ din switch.
Analog se întâmplă şi cu grupurile de litere m,M şi p,P.
Instrucţiuni iterative
Instrucţiunile iterative (repetitive sau de ciclare) permit ca
una sau mai multe instrucţiuni să fie repetate. Numărul de iteraţii
depinde de îndeplinirea unei condiţii. Dacă testul asupra condiţiei
se face înaintea instrucţiunilor care se repetă, se spune că iteraţia
este cu test iniţial; în caz contrar iteraţia este cu test final.
În limbajul C există două instrucţiuni cu test iniţial, while şi
for şi o instrucţiune cu test final, do - while.
INSTRUCTIUNEA while
Forma generală a instrucţiunii while este:
while(conditie)
instructiune;
unde:
conditie poate fi orice expresie;
instructiune poate fi o instrucţiune simplă, vidă
sau o instrucţiune compusă (numită şi corpul
ciclului).
Efectul instrucţiunii este următorul: se execută
instructiune cât timp conditie este adevărată (diferită de
zero). Atunci când conditie devine falsă (egală cu zero),
execuţia programului continuă cu instrucţiunea imediat
următoare. Organigrama de mai jos ilustrează sugestiv modul de
143
lucru al instrucţiunii while.
Fals
condiţie
Adevărat
instrucţiune
Observaţii:
Dacă din start condiţia este falsă, instructiune nu
se execută niciodată.
Ieşirea din ciclu se poate face normal (ca efect al
prelucrărilor din instructiune, atunci când după
un număr de paşi conditie devine falsă), anormal
(printr-o instrucţiune de salt care transferă execuţia
programului din interiorul ciclului în afara lui) sau
“niciodată“ (conditie rămâne mereu adevărată, şi
se obţine aşa zisa buclă eternă).
Prezentăm mai jos un exemplu de program unde apare
foarte naturală prezenţa testului iniţial în buclă şi deci folosirea
instrucţiunii while.
Exemplul 5.6
Calculul lungimii unui şir de caractere citit de la tastatură;
sfârşitul şirului este marcat de tasta Enter (caracterul ’\r’).
#include "stdio.h"
#include "conio.h"
void main(void)
{
int i=0;
printf("\n Tastati un sir:\n");
while (getche()!='\r')
i++;
printf("\n Lungimea sirului =%d",i);
getch();
}
144
INSTRUCTIUNEA for
În C, instrucţiunea for prezentă şi în alte limbaje, are
implementarea cea mai flexibilă. Ea depăşeşte cadrul tradiţional
în care este plasată de obicei: instrucţiune cu contor (variabilă
de control) recomandată spre a fi folosită ori de câte ori se
cunoaşte numărul de iteraţii.
Forma generală a instrucţiunii for este:
for(initializare;conditie;actualizare)
instructiune;
Exemplul 5.7
Programul realizează suma a n numere reale.
#include "stdio.h"
#include "conio.h"
void main(void)
{
float s=0,x;
145
int i,n;
printf("\n n=");
scanf("%i",&n);
for (i=0;i<n;i++)
{
printf("\n x=");
scanf("%f",&x);
s+=x;
}
printf("\n Suma este =%f",s);
getch();
}
Observaţii:
Componenta initializare a instrucţiunii for
poate conţine atribuiri care nu se referă neapărat la
variabila contor. În exemplul de mai sus iniţializarea
variabilei s se poate face în componenta
initializare a ciclului for cu ajutorul
operatorului virgulă, astfel:
for(s=0,i=0;i<n;++i)
{
. . . . . .
}
. . . . . .
Exemplul 5.8
Afişarea termenilor şirului lui Fibonacci mai mari ca 1 şi
mai mici ca un număr dat m. Şirul are forma 1, 1, 2, 3, 5,
8, …, adică primii doi termeni sunt egali cu 1, iar orice alt
termen se obţine ca sumă a celor doi termeni care-l preced.
#include "stdio.h"
#include "conio.h"
void main(void)
{
146
int a,b,c,m,i;
printf("\n Limita de afisare =");
scanf("%i",&m);
printf("\n Termenii sirului Fibonacci <
%i\n",m);
printf("\n 1 1 ");
for (i=3,a=b=1,c=2;c<m;i++)
{
printf("%i ",c);
a=b;b=c;
c=a+b;
}
getch();
}
Exemple:
Dacă în programul precedent renunţăm la ideea de a
afişa numărul de ordine al termenilor putem folosi
secvenţa:
for(a=b=1,c=2;c<m;)
{
printf(”\n Termenul =%i”,c)
a=b;b=c;
c=a+b;
}
147
creează un ciclu infinit sau o buclă eternă.
INSTRUCTIUNEA do-while
Este recomandabil să se folosească instrucţiunea do-while
când instrucţiunea care reprezintă corpul ciclului trebuie
executată cel puţin o dată.
Forma generală a acestei instrucţiuni este:
do
{
instructiuni
}
while(conditie);
instrucţiune
Adevărat
condiţie Fals
Observaţii:
Datorită aşezării testului de condiţie după corpul
ciclului, este evident că grupul de instructiuni se
execută cel puţin o dată.
Dacă în corpul ciclului nu se află instrucţiuni care să
148
conducă la o condiţie falsă după un număr finit de
ciclări (ieşire normală din ciclu) sau instrucţiuni de
salt din interiorul ciclului (ieşire anormală) se obţine
un ciclu infinit (buclă eternă).
Exemplul 5.9
Programul citeşte două numere a şi b de la tastatură şi
afişează suma lor. Procesul continuă cât timp la întrebarea
”Continuati?” se apasă una din tastele care conţin literele d
sau D.
#include "stdio.h"
#include "conio.h"
void main(void
{
float a,b;
char c;
do
{
printf("\n a=");
scanf("%f",&a);
printf("\n b=");
scanf("%f",&b);
printf("\n Suma a+b=%.2f",a+b);
printf("\n Continuati? (d/n) ");
c=getch();
}
while (c == 'D' || c == 'd');
}
Exemplul 5.10
Programul implementează un meniu simplu. Pentru două
numere citite de la tastatură se efectuează una din următorele
operaţii: suma, diferenţa produsul sau împărţirea (atunci când
este posibil) sau se iese din meniu.
#include "stdio.h"
#include "conio.h"
void main(void)
{
float a,b;
char ch;
printf("\n a=");scanf("%f",&a);
printf("\n b=");scanf("%f",&b);
149
printf("\n + Adunare");
printf("\n - Scadere");
printf("\n * Inmultire");
printf("\n / Impartire");
printf("\n r Renunta!");
printf("\n Introduceti optiunea dvs:");
do
{
ch=getchar();
switch(ch)
{
case '+' :printf("\n a+b=%.2f",a+b);
break;
case '-' :printf("\n a-b=%.2f",a-b);
break;
case '*' :printf("\n a*b=%.2f",a*b);
break;
case '/' :if (b)
printf("\n a/b=%.2f",a/b);
else
printf("\n Impartire
imposibila!"); break;
case 'r' :
case 'R' :exit(0);
}
}
while (ch!='+' && ch!='-' && ch!='*' && ch!='/');
getch();
}
Exemplul 5.11
Programul calculează şi afişează radicalul dintr-un număr.
Noutatea faţă de Exemplul 5.1 este apariţia unei bucle iterative
de validare: ieşirea din buclă urmată de calculul radicalului se
face doar atunci când numărul citit de la tastatură este pozitiv.
150
#include "stdio.h"
#include "conio.h"
#include "math.h"
void main(void)
{
float x;
do
{
printf("\n x=");
scanf("\n %f",&x);
}
while (x<0);
printf("\n Radical din x=%.2f este
y=%.4f",x,sqrt(x));
getch();
}
Exemplul 5.12
Programul ilustrează folosirea ciclurilor imbricate:
#include "stdio.h"
#include "conio.h"
void main(void)
{
int i,j;
for (i=1;i<=5;i++)
{
for (j=1;j<=i;j++)
printf("%2d",j);
printf("\n");
};
getch();
}
151
Rezultatul execuţiei programului de mai sus este:
1
1 2
1 2 3
1 2 3 4
1 2 3 4 5
Exemplul 5.13
Programul rezolvă următoarea problemă: cât timp se
citeşte de la tastatură o valoare x diferită de zero se afişează
şirul de numere x, x+1, x+2, x+3, x+4. Acest proces
continuă sau se întrerupe la cerere.
#include "stdio.h"
#include "conio.h"
void main(void)
{
int x,i;
char ch;
do
{
printf("\n x=");
scanf("%i",&x);
while (x)
{
for (i=0;i<5;i++)
printf("%5d",x+i);
printf("\n x=");
scanf("%i",&x);
}
printf("\n Continuati ? (d/n)");
ch=getch();
}
while (ch == 'd' || ch == 'D');
}
152
Instrucţiuni de salt
În limbajul C există patru instrucţiuni care execută un salt
necondiţionat în program: break, continue, goto, return.
Instrucţiunea return se referă la revenirea din funcţia apelată la
punctul unde s-a făcut apelul.
INSTRUCTIUNEA break
După cum s-a văzut la prezentarea instrucţiunii switch,
instrucţiunea break poate încheia execuţia unei prelucrări case şi
forţa trecerea execuţiei la prima instrucţiune aflată după switch.
O altă situaţie unde instrucţiunea break îşi dovedeşte utilitatea
este atunci când se doreşte încheierea forţată a unui ciclu. În acest
caz întâlnirea instrucţiunii break în corpul ciclului determină
întreruperea ciclării şi trecerea controlului la prima instrucţiune
care urmează după ciclu.
Exemplul 5.14
Programul “extrage“ şi afişează cel mult 20 de numere
aleatoare folosind funcţia rand(). Dacă s-a “extras“ numărul 10
programul nu mai efectuează restul “extragerilor“.
#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
void main(void)
{
int i,x;
for (i=0;i<20;i++)
{
x=rand()%20+1;
printf("\n %i. S-a extras numarul
%i",i+1,x);
if (x==10) break;
}
getch();
}
153
care se află, nu şi eventualele instrucţiuni switch sau de ciclare în
care ar putea fi inclusă prima.
Exemplul 5.15
Programul tipăreşte de 10 ori câte 7 numere extrase
aleator.
#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
void main(void)
{
int i,j;
for (i=0;i<10;i++)
{
printf("\n");
for (j=0;j<10;j++)
{
printf("%5d",rand()%10+1);
if (j>=7) break;
}
}
getch();
}
INSTRUCŢIUNEA continue
Instrucţiunea continue se foloseşte numai în corpul unui
ciclu; ea forţează execuţia următoarei iteraţii a ciclului,
omiţându-se instrucţiunile prezente între cele două iteraţii (locul
unde se află plasată în corpul ciclului şi sfârşitul acestuia).
Efectul instrucţiunii este următorul:
Când continue este întâlnită într-un ciclu for se
continuă cu execuţia componentei de actualizare şi
apoi a testului condiţional.
Când este întâlnită într-un while sau do-while, se
trece la execuţia expresiei condiţionale.
Exemplul 5.16
Programul citeşte de la tastatură 10 numere întregi
însumându-le doar pe cele strict pozitive.
154
#include "stdio.h"
#include "conio.h"
void main(void)
{
int i,x,s;
for (i=s=0;i<10;i++)
{
printf("\n x=");
scanf("%i",&x);
if (x<=0) continue;
s+=x;
}
printf("\n Suma este=%d",s);
getch();
}
INSTRUCTIUNEA goto
Forma generală a instrucţiunii goto este:
goto eticheta;
.
.
.
eticheta:instructiune;
Exemplul 5.17
Programul reprezintă altă implementare a Exemplului 5.10.
#include "stdio.h"
#include "conio.h"
155
void main(void)
{
float a,b;
char ch;
for(;;)
{
clrscr();
printf("\n a=");
scanf("%f",&a);
printf("\n b=");
scanf("%f",&b);
printf("\n + Adunare");
printf("\n - Scadere");
printf("\n * Inmultire");
printf("\n / Impartire");
printf("\n r Renunta");
printf("\n Introduceti optiunea
dvs:");
ch=getche();
switch (ch)
{
case '+' :printf("\n a+b=%.2f",a+b);
break;
case '-' :printf("\n a-b=%.2f",a-b);
break;
case '*' :printf("\n a*b=%.2f",a*b);
break;
case '/' :if (b)
printf("\n a/b=%.2f", a/b);
else
printf("\n Impartire
imposibila"); break;
case 'r' :
case 'R' :goto STOP;
}
getch();
}
STOP:printf("\n Am renuntat!");
getch();
}
156
� Test de autoevaluare
5.1. Secvenţa de program
int x=-3,y=7;
if (x>0)
printf(”\n x=%i”,x);
else
if (y)
printf(”\n y=%i”,y);
else
printf(”\n y=0”);
a. afişează y=7
b. este greşită deoarece o instrucţiune if conţine o altă
instrucţiune if
c. afişează x=-3
5.2. Secvenţa de program
if(x)
if(y)
y=3;
else
y=5;
este echivalentă cu
a. if(x)
if(y)
y=3;
else;
else
y=5;
b. if(x&&y)
y=3;
else
y=5;
c. if(x)
{
if(y)
y=3;
157
}
else
y=5;
a. este greşită
b. este echivalentă cu
if (x!=0)
y=1/x;
c. este chivalentă cu
if x!=0
y=1/x;
158
5.6. Secvenţa de program
int x=3,y=6;
if (x>0)
printf(”\n x=%i”,x);
else
y=x+3;
printf(”\n y=%i”,y);
afişează
a. x=3
b. y=6
c. x=3
y=6
5.7. Secvenţa de program
int x=3,y=4;
printf(”\n %i”,x>y?x:y);
a. afişează 3
b. afişează 4
c. este greşită deoarece argumentul funcţiei printf()
este o expresie, nu o variabilă.
5.8. Secvenţa de program
char x=’a’;
switch(x)
{
case ’a’:printf(”\n amic”);
case ’A’:printf(”\n Amare”);
}
a. afişează amic
b. afişează Amare
c. afişează
amic
Amare
5.9. Secvenţa de program
int x=3;
if (x=4)
159
printf(”\n x=%i”,x);
a. este greşită
b. este corectă, dar nu afişează nimic
c. este corectă şi afişează valoarea 4
d. este corectă şi afişează valoarea 3
5.10. Secvenţa de program
char x=’a’;
switch(x)
{
case ’a’:printf(”\n amic”);break;
case ’A’:printf(”\n Amare”);
}
a. afişează amic
b. afişează Amare
c. afişează
amic
Amare
d. este greşită deoarece al doilea case nu se termină cu
break
5.11. Secvenţa de program
int i=3;
while(i)
i--;
printf(”%3i”,i);
a. afişează 2 1 0
b. conţine o buclă eternă
c. afişează 0
5.12. Secvenţa de program
int i=3;
while(i)
printf(”%3i”,i);
i--;
160
eternă)
c. afişează 3 2 1
5.13. Secvenţa de program
int i=3;
while(i);
printf(”%3i”,i);
i--;
a. afişează 3 2 1 0
b. afişează 3 2 1
c. conţine o buclă eternă
5.15. Secvenţa de program
int i=0;
while(i)
printf(”%3i”,i);
a. afişează valoarea 0
b. afişează valoarea 0 de o infinitate de ori (buclă
eternă)
c. nu afişează nimic
5.16. Secvenţa de program
int i=0;
for (;i<3;i++);
printf(”%3i”,i);
161
a. este greşită sintactic deoarece lipseşte componenta
de iniţializare a instrucţiunii for
b. afişează valorile 0 1 2 3
c. afişează valorile 0 1 2
d. afişeaza valoarea 3
e. conţine o buclă eternă afişându-se permanent
valoarea 0
f. conţine o buclă eternă şi nu afişează nimic
5.17. Secvenţa de program
int i,j;
for (i=1,j=10;i<=5;i++,j--)
printf(”\n %i %2i”,i,j);
a. nu afişează nimic
b. afişează 0 -1 -2 -3
c. conţine o buclă eternă
5.19. În secvenţa de program
int x=1,i;
for(i=1;x<=3;i++)
scanf(”%i”,&x);
162
a. funcţia scanf() se execută de 3 ori
b. funcţia scanf() se execută de o infinitate de ori
c. instrucţiunea for este greşită deoarece contorul i nu
se testează niciodată
d. se iese din buclă numai după ce s-a citit o valoare
x>3
5.20. Secvenţa de program
int i;
for(i=1,i<=3;i++)
printf(”%3i”,i)
a. este greşită
b. conţine o buclă eternă
c. afişează 1 2 3
5.21. Secvenţa de program
int i;
for (i=1,i<=3;i++)
printf(”%3i”,i)
163
c. este greşită deoarece funcţia scanf() nu este pusă
între acolade
d. nu execută nici o citire a lui x
5.24. Secvenţa de program
int j;
do
j=3;
while (j<=4);
{
printf(”%3i”,j);
j++;
}
a. afişează valoarea 3
b. afişează valorile 3 4
c. conţine o buclă do-while eternă
d. conţine o buclă while eternă
e. este greşită
5.25. Secvenţa de program
int i=1;
do
printf(”\n%i”,i);
i++;
while(i<=2);
a. afişează 1 2
b. este greşită deoarece instrucţiunile dintre do şi while
trebuie să fie cuprinse între acolade
5.26. Secvenţa de program
int i,j;
for(i=1;i<=2;i++)
for(j=1;j<=2;j++)
printf(”\n i=%i j=%i”,i,j);
164
i=2 j=2
c. afişează i=1 j=1
i=2 j=1
i=1 j=2
i=2 j=2
5.27. Secvenţa de program
int i,j;
for(i=1;i<=3;i++)
{
printf(”\n”);
for(j=1;j<=i;j++)
printf(”%3i”,j);
}
a. este greşită deoarece limitele de variaţie ale
contorului j depind de contorul i al primului ciclu
b. este corectă şi afişează
1
1 2
1 2 3
c. este corectă şi afişează
1 2 3
1 2
1
5.28. Secvenţa de program
int i;
for(i=1;i<=5;i++)
{
printf(”%3i”,i);
if(i==3)break;
}
165
{
printf(”\n Sunt aici!”);
if (!j)break;
}
a. afişează mesajul Sunt aici! de 2 ori
b. afişează mesajul Sunt aici! de 30 ori
c. afişează mesajul Sunt aici! o dată
5.30. Secvenţa de program
int s,i;
for(s=0,i=10;i;i--)
{
s+=i;
if(i-5)continue;
}
166
c. calculează suma s=5
5.33. Secvenţa de program
int i=1;
while(i<3)
{
if!(i==2)continue;
printf(”%3i”,i);
i++;
}
167
Tablouri şi şiruri de caractere
Notaţia indicială a variabilelor nu este nouă; ea a fost şi este
folosită în special de matematicieni ori de câte ori este nevoie ca
o prelucrare să fie exprimată cît mai sintetic. Este evident că
prelucrarea S=a+b+c+d+e+f arată mult mai puţin elegant decât
6
S xi În ultimul caz cele şase variabile a,b,c,d,e,f au
i 1
fost redenumite x1,x2,...,x6; ele pot fi privite astfel drept
primele 6 componente ale vectorului x.
Tablourile reprezintă tocmai implementarea noţiunilor de
vector, matrice sau masiv multidimensional într-un limbaj de
nivel înalt. Ele reprezintă colecţii omogene de date (adică de
acelaşi tip), stocate în locaţii de memorie învecinate. Accesul la
oricare din elementele tabloului se face cu ajutorul indicilor.
Tablouri unidimensionale
Declaraţia unui tablou unidimensional se face după forma
generală:
tip nume_tablou[dim];
unde:
tip reprezintă tipul de bază al elementelor indexate;
dim reprezintă numărul de elemente ale tabloului;
nume_tablou este un identificator reprezentând
numele tabloului.
Dimensiunea zonei continue alocate se calculează prin
relaţia
dimens_alloc=dim*sizeof(tip).
168
Observaţii:
alocarea se face în timpul compilării;
o dată făcută alocarea, în scopul măririi vitezei de
execuţie nu se mai face nici o verificare a
dimensiunii; gestionarea corectă a zonei de memorie
alocate cade, deci, exclusiv în sarcina
programatorului.
Referirea la un element al tabloului unidimensional se face
precizând numele tabloului urmat de o expresie întreagă între
paranteze drepte, adică
nume_tablou[expr]
Exemplul 5.18
Comutarea componentelor unui vector şi afişarea lor în
coloană.
#include "stdio.h"
#include "conio.h"
void main(void)
{
int x[50],i,n,c;
169
scanf("%d",&n);
for (i=0;i<n;i++)
{
printf("\n x[%i]=",i);
scanf("%i",&x[i]);
}
/* comutarea elementelor */
for (i=0;i<n/2;i++)
{
c=x[i];
x[i]=x[n-1-i];
x[n-1-i]=c;
}
Tablouri multidimensionale
Dacă elementele unui tablou unidimensional sunt la rîndul
lor tablouri unidimensionale obţinem un tablou bidimensional
sau o matrice. De exemplu, declaraţia:
int x[4][3];
170
Observaţii:
Referirea clasică la elementele unui tablou prin
separarea indicilor prin virgulă este incorectă în C şi
are semnificaţia rezultată din folosirea operatorului de
secvenţiere. De exemplu, considerând declaraţia de
mai sus, referirea x[i,j] este echivalentă cu x[j].
Dimensiunea zonei continue de memorie alocate este
dată (în octeţi) de valoarea dim1*dim2*dim3*dimn*
*sizeof(tip).
Exemplul 5.19
Calculul şi afişarea sumei a două matrici a şi b de
dimensiune 4x3 citite de la tastatură.
#include "stdio.h"
#include "conio.h"
void main(void)
{
int a[10][10],b[10][10],c[10][10];
short i,j,m,n;
171
c[i][j]=a[i][j]+b[i][j];
Iniţializarea tablourilor
Exemplele anterioare ne-au arătat cum se poate iniţializa un
tablou prin valori date de la tastatură. Există însă posibilitatea
iniţializării unui tablou printr-o definiţie de forma:
declaratie tablou={lista valori_initiale};
172
În general, iniţializarea elementelor unui tablou
multidimensional se face după regula “ultimul indice variază cel
mai rapid“, care este o generalizare a regulii de memorare “pe
linii“. Astfel, cele douăsprezece componente ale tabloului
b[3][2][2] vor fi iniţializate astfel:
b[0][0][0]=1
b[0][0][1]=2
b[0][1][0]=3
b[0][1][1]=4
b[1][0][0]=5
b[1][0][1]=6
b[1][1][0]=7
b[1][1][1]=8
b[2][0][0]=9
b[2][0][1]=10
b[2][1][0]=11
b[2][1][1]=12
173
Tablouri şi şiruri de caractere
În C nu există un tip special pentru definirea unui şir de
caractere. Şirurile de caractere se construiesc cu ajutorul
tablourilor unidimensionale.
Declaraţia unui şir cu numele, nume_sir de lungime
maxim dim-1 caractere se face sub forma:
char nume_sir[dim];
174
elementelor din şir.
Legătura dintre şiruri şi tablouri unidimensionale permite
referirea indexată la caracterele şirului. Folosind acest lucru, în
exemplul de mai jos se selectează şi afişează literele mici din
şirul sir.
Exemplul 2.10
Selectarea şi afişarea literelor mici dintr-un şir.
#include "stdio.h"
#include "conio.h"
void main(void)
{
int i;
char sir[]="aAbBcCdD";
printf("\n Sirul este: %s",sir);
printf("\n Literele mici din sir sunt: ");
for (i=0;sir[i];i+=2)
printf("%c",sir[i]);
getch();
}
Exemplul 5.21
Citirea a două şiruri sub forma nume prenume şi afişarea
lor sub forma prenume nume.
#include "stdio.h"
#include "conio.h"
void main(void)
{
char nume[25],prenume[25];
printf("\n Numele=");
scanf("%s",nume);
printf("\n Prenumele=");
scanf("%s",prenume);
printf("\n %s %s",prenume,nume);
getch();
}
175
Pentru citirea unui şir de la tastatură se poate folosi funcţia
gets() cu forma generală:
gets(sir_destinatie);
176
adaugă sir2 la sfârşitul şirului sir1 (concatenare).
Exemplul 5.22
Se citeşte de la tastatură un număr neprecizat de şiruri de
caractere. Citirea se termină când se întâlneşte şirul ”stop”.
Programul stabileste şirul “minim” (în sens lexicografic) şi îl
afişează împreună cu lungimea sa.
#include "stdio.h"
#include "conio.h"
#include "string.h"
void main(void)
{
char min[20],x[20];
printf("\n Introduceti siruri de caractere ! ");
printf("\n La sfarsit tastati STOP \n");
strcpy(min,gets(x));
while (strcmp(x,"stop"))
{
strcmp(min,x)<0 ? min : strcpy(min,x);
gets(x);
}
printf("\n Sirul minim este "); puts(min);
printf("\n si are lungimea %i",strlen(min));
getch();
}
� Test de autoevaluare
5.35. Declaraţia
float x[100];
înseamnă
a. rezervarea în memorie a 100 de locaţii la adrese
consecutive
b. rezervarea în memorie a 100de locaţii la adrese
întâmplătoare
c. rezervarea a 100 de octeţi pentru variabila reală x
177
5.36. Secvenţa de program
int x[m][n],m=3,n=2;
a. sunt echivalente
b. nu sunt echivalente
5.40. În urma iniţializării tabloului a
int a[3][2]={1,2,3,4,5,6};
178
componenta a[1][0] are valoarea
a. 2
b. 3
c. altă valoare decât decât 2 sau 3
5.41. Iniţializarea
int a[3][2]={1,2,3,4,5,6};
este echivalentă cu:
a. int a[3][2]={
{1,2},
{3,4},
{5,6},
};
b. int a[3][2]={
{1,4},
{2,5},
{3,6},
};
5.42. Iniţializarea
float x[2][3]={1,2,3,4,5,6};
este echivalentă cu
a. float x[][]={1,2,3,4,5,6};
b. float x[][3]={1,2,3,4,5,6};
c. float x[2][]={1,2,3,4,5,6};
5.43. Secvenţa de program
int x[10],i;
for(i=1;i<=10;i++)
scanf(”%d”,&x[i]);
179
b. iniţializarea char x[4]={’a’,’b’,’c’};
c. iniţializarea char x[]={’a’,’b’,’c’,’\0’};
5.45. Secvenţa de program
char x[]=”abcd”;
putch(x[1]);
180
x=”Ploiesti”;
atribuirea
x=”Ploiesti”;
a. este greşită
b. este greşită, iar copierea şirului ”Ploiesti” în
variabila x se realizează prin strcpy(x,”Ploiesti”);
c. este corectă
5.50. Secvenţa de program
char x[20];
gets(x);
puts(x);
afişează acelaşi şir dacă înlocuim gets(x); cu:
a. gets(&x);
b. scanf(”%s”,&x);
c. scanf(”%s”,x);
5.51.În secvenţa de program
int i;
char x[20]=”xyzw”;
puts(x);
apelul
puts(x);
181
5.21 a 5.22 b 5.23 b 5.24 c 5.25 b
5.26 b 5.27 b 5.28 b 5.29 a 5.30 b
5.31 c 5.32 a 5.33 a 5.34 b, c, d
5.35 a 5.36 c 5.37 b 5.38 b 5.39 b
5.40 b 5.41 a 5.42 b 5.43 b 5.44 c
5.45 b 5.46 b 5.47 c 5.48 a
5.49 a, b 5.50 a, b, c 5.51 a, b
Rezumat
Instrucţiunile de control ale limbajului C, care sunt
implementările, specifice limbajului, ale structurilor algoritmice
fundamentale discutate în UI4, sunt următoarele:
instrucţiunea expresie
instrucţiunile de decizie: if (if-else şi varianta if cu
ramură vidă) şi switch, la care se adaugă operatorul
condiţional ?:
instrucţiunile iterative (repetitive sau de ciclare):
while, for şi do - while
182
instrucţiunile de salt: break, continue, goto, return
Există posibilitatea ca o instrucţiune decizională să includă
o altă instrucţiune decizională şi ca o instrucţiune iterativă să
includă o altă instrucţiune iterativă; se spune în acest caz că
instrucţiunile sunt imbricate sau incluse.
Instrucţiunea break poate încheia execuţia unei prelucrări
case din instrucţiunea switch sau poate încheia forţat un ciclu.
Instrucţiunea continue, folosită numai în corpul unui ciclu,
forţează execuţia următoarei iteraţii a ciclului, omiţându-se
instrucţiunile prezente între cele două iteraţii (locul unde se află
plasată în corpul ciclului şi sfârşitul acestuia).
Instrucţiunea goto realizează un salt necondiţionat la o
instrucţiune identificată prin eticheta care urmează instrucţiunea
goto. Saltul poate fi făcut înainte sau înapoi.
Evident că în programe aceste instrucţiuni se pot combina şi
include unele în altele după cum cere algoritmul proiectat pentru
a rezolva o anume problemă.
Tablourile, acele structuri de date care reprezintă colecţii
omogene de date stocate în locaţii de memorie învecinate, sunt
implementările noţiunilor de vector (când există o singură
dimensiune), matrice (când se consideră două dimensiuni) sau
masiv multidimensional (când se consideră mai mult de două
dimensiuni) în limbajele de nivel înalt.
Un exemplu de vector, unul de matrice şi respectiv unul de
masiv multidimensional, declarate în C, sunt următoarele:
int v[50];
float a[10][20];
int t[2][2][6][10][3];
183
se face în timpul compilării, iar dimensiunea acestui spaţiu nu
poate fi modificată pe parcursul execuţiei programului – un
tablou este un tip de dată alocat static. O dată făcută alocarea,
compilatorul nu mai face nici o verificare a dimensiunii şi prin
urmare gestionarea corectă a zonei de memorie alocate cade
exclusiv în sarcina programatorului.
Tablourile se pot iniţializa ca în exemplele:
int v[6]={-7,-2,95,21,5,-23};
float a[3][2]={1,2,3,4,5,6};
184
Bibliografie
185
Bibliografia cursului
186