| |
Instructiuni
|
Instructiunea expresie
|
Sintaxa:
expresie;
//
a
se observa faptul ca orice instructiune expresie se termina cu ;
Expresia
este evaluata cu efect lateral, deci de regula instructiunea expresie este
o atribuire ( expresie in care apare unul sau mai multi operatori de atribuire
) sau un apel de functie - vezi
definitia expresiei.
Exemple:
int a,b,c,m,n,p=2;
// liniile
de mai jos reprezinta instructiuni expresie
scanf("%d",&a); //
apel de functie, valoarea returnata nu este folosita
b=5;
c=a>b?a:b;
n=printf("%d %d %d\n",a,b,c); //valoarea
returnata este memorata in n
p=a*b/c;
p++;
m=p+=5;
a+b; //
valoarea expresiei nu este folosita - apare un avertisment ( warning
) la compilare:
// Code
has no effect
Instructiunea
expresie are ca echivalent ( mai slab ) in Pascal instructiunea de atribuire
( var:=expr ). In Pascal instructiunile se separa prin ; pe cand in C se
termina, lucru care se pare duce la un numar mai mic de erori in compilare.
Un bloc de atribuire dintr-o schema logica se codifica printr-o intructiune
expresie.
Instructiunea compusa (bloc )
|
Pe
parcursul elaborarii programelor, intervin situatii cand sintaxa impune
folosirea unei singure instructiuni, iar codificarea necesita prezenta
mai multora - instructiunile se intercaleaza intre acolade, formand o instructiune
compusa.
Sintaxa:
{
declaratii_variabile_locale_blocului
//
optionale
instructiuni
}
Observatii:
-
Corpul
oricarei functii este un bloc;
-
Instructiunile
unui bloc pot fi de orice tip, deci si alte instructiuni bloc; instructiunile
bloc pot fi deci incuibate;
-
Un bloc
corespunde structurii de control secventa
de la schemele logice;
-
O instructiune
bloc poate sa nu contina nici o declaratie sau instructiune intre acolade;
in general un astfel de bloc poate apare in faza de punere la punct a programului
( functii cu corp vid );
-
Daca un
bloc contine doar instructiuni expresie, el se poate inlocui cu o instructiune
expresie in care expresiile initiale se separa prin operatorul secvential
,
;
exemplu:
Blocul:
{
a++;
c=a+ --b;
printf("%d\n",c);
}
este echivalent cu instructiunea expresie:
a++,c=a+ --b,printf("%d\n",c);
Instructiunea vida
|
Se
utilizeaza cand sintaxa impune prezenta unei instructiuni, iar codificarea
nu cere nici una.
Sintaxa:
;
Instructiunea de decizie
|
Sintaxa:
if(expresie)
sau
if(expresie)
instructiune1
instructiune
else
instructiune2
Semantica:
Se
evalueaza expresie; daca valoarea ei este adevarat ( diferita de 0 ) se
executa instructiune1, altfel, daca exista ramura else, se executa instructiune2.
Observatii:
-
Instructiunea
corespunde structurii de control selectie din schemele logice;
-
Pentru
ca programele scrise se fie cat mai clare este bine ca instructiunile corespunzatoare
lui if
si else
sa fie scrise decalat fata de cuvintele cheie;
-
Instructiunea
corespunzatoare valorii adevarat sau fals, poate fi orice instructiune
C:
-
daca instructiunea
corespunzatoare valorii adevarat este o instructiune expresie, simbolul
; apare in fata cuvantului cheie else
-
instructiunea
bloc ( atunci cand trebuie executate mai multe prelucrari )
-
o alta
instructiune de decizie - deci instructiunile if-else
pot fi incuibate; fiecare else
corespunde
if-ului
anterior cel mai apropiat, fara pereche.
Exemplu:
//
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 adev nu se executa nimic, deci apare instr 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"); |
Instructiunea de ciclare cu test initial
|
Sintaxa:
while(expresie)
instructiune
Semantica:
Se
evalueaza expresie;
daca valoarea ei este adevarat ( diferita de 0 ) se executa instructiune,
dupa care se evalueaza din nou expresie;
daca valoarea este 0, se trece la instructiunea urmatoare. Deci instructiune,
care este corpul ciclului, se executa atat timp cat expresie
este adevarata, deci de 0 sau mai multe ori.
Observatii:
-
In general
expresie
contine variabile care se modifica in instructiune,
astfel incat expresie sa devina falsa, deci ciclarea sa nu se faca infinit;
-
In unele
programe se poate sa apara
corpul ciclului poate sa contina o instructiune de iesire din ciclu, altfel
tastarea Ctrl/Break intrerupe programul;
-
Orice
program C poate fi scris folosind instructiunile prezentate pana acum;
urmatoarele doua instructiuni de ciclare sunt derivate din cea cu test
initial;
-
Instructiunea
while
corespunde structurii ciclu cu test initila de la schemele logice.
Aplicatii:
-
1.Secvente
echivalente care citesc cu validare o variabila - in urma citirii, variabila
trebuie sa apartina intervalului [inf,sup]:
putchar(':');
scanf("%d",&var);
while(var<inf
|| var>sup){ //valoare
invalida, se reia citirea
putchar(':');
scanf("%d",&var);
} |
| while(putchar(':'),scanf("%d",&var),var<inf
|| var>sup); |
| for(;putchar(':'),scanf("%d",&var),var<inf
|| var>sup;); |
do{
putchar(':');
scanf("%d",&var);
}while(var<inf
|| var>sup); |
-
2.Se
citesc de la tastatura intregi, pana la introducerea lui CTRL/Z. Sa se
determine si sa se tipareasca urmatoarele informatii:
-
numarul
de valori citite
-
media
aritmetica a valorilor
-
numarul
de valori pozitive
-
valoarea
minima.
#include
<stdio.h>
#include
<conio.h>
#define
MAX 32767 //0x7fff
void
main(void){
//var
locale
int curent,ind/*preia
val returnata de scanf*/,contor,contor_poz,min;
float med_aritm; long suma; //pentru
a nu apare depasire
//initializari
//*
contor=contor_poz=suma=0;min=MAX;
//prima
citire
putchar(':');ind=scanf("%d",&curent); //1
while(ind!=EOF){
//2
//prelucrarea
valorii din curent
contor++;
suma+=curent;
if(curent>0)contor_poz++;
if(curent<min)min=curent;
//citirea
unei noi valori
putchar(':');ind=scanf("%d",&curent); //3
}//while
//**
//tiparire
rezultate
if(contor){
med_aritm=suma/(float)contor;
printf("S-au citit %d intregi, dintre care %d pozitive, cu media \
aritm
%f, minimul %d\n",contor,contor_poz,med_aritm,min);
}//if
else
puts("Nici o valoare prelucrata");
getch();
}//main |
Programul
se mai poate scrie echivalent daca liniile notate cu 1 si 3 dispar, iar
2 va fi de forma ( expresie formata din doua subexpresii, separate de operatorul
secvential ):
while(putchar(':'),scanf("%d",&curent)!=EOF){
//2
Daca
enuntul se modifica astfel incat citirea sa se faca pana la introducerea
lui 0, care nu se prelucreaza, linia 2 devine:
while(putchar(':'),scanf("%d",&curent),curent){
//2
Daca
enuntul se modifica astfel incat citirea sa se faca pana la introducerea
lui CTRL/Z sau 0, care nu se prelucreaza, linia 2 devine:
while(putchar(':'),scanf("%d",&curent)!=EOF
&& curent){//2
Instructiunea de ciclare for
|
Sintaxa
-
in
dreapta secventa echivalenta care foloseste instructiunea
while:
for(expresie1;expresie2;expresie3)
instructiune |
expresie1;
while(expresie2){
instructiune
expresie3;
} |
Semantica:
Se
evalueaza expresie1
care
are rol de initializare; se evalueaza apoi
expresie2, cu rol de conditie
- daca valoarea ei este adevarat ( diferita de 0 ) se executa instructiune
-
corpul
ciclului, dupa care se evalueaza expresie3,
cu rol de actualizare, apoi din nou expresie2;
daca valoarea este 0, se trece la instructiunea urmatoare. Deci instructiune
se executa atat timp cat expresie2
este adevarata, deci de 0 sau mai multe ori.
Observatii:
-
Instructiunea
for
permite
o scriere mult mai compacta decat celelalte doua instructiuni de ciclare,
fiind foarte des utilizata in scrierea programelor;
-
Oricare
din cele expresii poate lipsi, dar separatorul ; ramane. Absenta expresie2
echivaleaza cu conditia adevarat, deci 1; in tabelul de mai jos sunt date
echivalentele cu instructiunea while,
pentru cazuri cand expresii din sintaxa for
lipsesc:
for(;expresie;)
instructiune |
while(expresie)
instructiune |
for(;;)
instructiune |
while(1)
instructiune |
-
Instructiunea
for are ca si caz particular instructiunea
de ciclare cu contor - in Pascal instructiunea for
are doar aceasta semnificatie:
for(var_contor=val_initiala;var_contor<=val_finala;var_contor+=increment)
instructiune
numarul
de cicluri fiind (val_finala-val_initiala)/increment
Aplicatii:
-
1.Folosind
instructiunea for,
programul
anterior devine - modificari apar in secventa marcata //*
//** - a se observa ca fiecare expresie din
for
este formata din mai multe, separate prin operatorul secvential:
#include
<stdio.h>
#include
<conio.h>
#define
MAX 32767 //0x7fff
void
main(void){
//var
locale
int curent,ind/*preia
val returnata de scanf*/,contor,contor_poz,min;
float med_aritm; long suma; //pentru
a nu apare depasire
//*
for(contor=contor_poz=suma=0,min=MAX;putchar(':'),scanf("%d",&curent)!=EOF;
contor++,suma+=curent){
if(curent>0)contor_poz++;
if(curent<min)min=curent;
}//for
//**
//tiparire
rezultate
if(contor){
med_aritm=suma/(float)contor;
printf("S-au citit %d intregi, dintre care %d pozitive, cu media aritm\
%f, minimul %d\n",contor,contor_poz,med_aritm,min);
}//if
else
puts("Nici o valoare prelucrata");
getch();
}//main |
-
2.Pentru
un intreg n strict pozitiv citit de la tastatura, sa se calculeze expresiile:
-
suma primilor
n intregi
-
factorial
de n
-
puterea
n a lui n.
A se observa
la rularea programului depasirile care apar ( 6^6 depaseste domeniul intreg
) si sa se faca modificarile necesare pentru calcularea corecta a expresiilor;
sa se observe valorile lui n pentru care apar depasiri la declararea variabilelor
de calcul de tip int ( 6^6), long ( 12^12 ), float, double.
#include
<stdio.h>
#include
<conio.h>
void
main(void){
//var
locale
int n,contor,suma,factorial,putere;
//citire
n cu validare
while(printf("n="),scanf("%d",&n),n<=0);
//calcul
expresii
for(suma=0,contor=factorial=putere=1;contor<=n;contor++){
suma+=contor;
factorial*=contor;
putere*=n;
}//for
//tiparire
rezultate
printf("suma=%d,fact=%d,putere=%d\n",suma,factorial,putere);
getche();
}//main
//instructiunea
for
se mai poate scrie - cu corpul vid:
for(suma=0,contor=factorial=putere=1;contor<=n;suma+=contor,factorial*=contor,
putere*=n, contor++); |
Sa se
modifice programul astfel incat sa se citeasca o secventa de intregi pentru
care sa se calculeze expresiile.
-
3.Sa se
tipareasca in binar numerele intregi citite - oprirea programului se face
cu CTRL/Z.
#include
<stdio.h>
#include
<conio.h>
void
main(void){
int
numar,rang,dim=sizeof(numar)*8/*numar
biti*/,masca=1;
while(1){
printf("numar=");scanf("%d",&numar);
for(rang=dim-1;rang>=0;rang--)
putchar(numar&masca<<rang?'1':'0'); //tip
bit de la pozitia rang
putchar('\n');
} |
Instructiunea de ciclare cu test final
|
Sintaxa
- in
dreapta secventa echivalenta care foloseste instructiunea while:
do
instructiune
while(expresie); |
instructiune
while(expresie)
instructiune |
Semantica:
Se
executa instructiune
- corpul ciclului, apoi se evalueaza expresie
care are rol de conditie - daca valoarea ei este adevarat ( diferita
de 0 ) se executa instructiune
, dupa care se evalueaza din nou expresie;
daca valoarea este 0, se trece la instructiunea urmatoare. Deci instructiune
se executa atat timp cat expresie
este adevarata, cel putin o data.
Observatii:
-
Instructiunea
do-while
se utilizeaza in secventele in care se stie ca o anumita prelucrare trebuie
executata cel putin o data - vezi citirea cu validare;
-
Instructiunea
echivaleaza cu structura de control ciclu cu test final de la scheme logice;
-
Instructiunea
do-while
difera de repeat until
din Pascal, unde corpul ciclului se executa cat timp o conditie este falsa.
Aplicatie:
Sa
se calculeze suma termenilor sirului an=xn/n!, a0=1,
pana la insumarea a cel mult nmax termeni sau pana cand diferenta a doi
termeni consecutivi este eps. Se vor citi de la tastatura cu validare valorile:
x ( 0<x<1 ), nmax ( nmax >=2 ), eps ( 0<eps<1).
Se
vor afisa suma calculata, numarul de termeni insumati si diferenta dintre
ultimii doi termeni consecutivi.
Se
observa ca sirul este descrescator, iar relatia de recurenta este: an=an-1x/n
In
rezolvarea acestei aplicatii se utilizeaza instructiunea do-while
pentru
ca prelucrarea ce formeaza corpul ciclului trebuie executata cel putin
o data ( suma se initializeaza cu primul termen si cel putin inca unul
mai trebuie adunat, nmax fiind >=2 ).
#include
<stdio.h>
#include
<conio.h>
void
main(void){
int nmax,rang;
float x,eps,suma,termen,termen_ant;
/*double pentru precizie mai mare */
//initializari
rang=0;
suma=termen=0; //suma
se initializeaza cu primul termen ( de rang 0 )
//citiri cu validari
while(printf("x="), scanf("%f",&x), x<=0 || x>=1);
while(printf("nmax="), scanf("%d",&nmax), nmax<2);
while(printf("eps="), scanf("%f",&eps), eps<=0 || eps>=1);
//calcul
suma
do{
termen_ant=termen; //salvare
termen in termen_ant
termen=x*termen_ant/++rang; //calcul
cu relatia de recurenta
//val
rang reprezinta numarul de termeni insumati-1
suma+=termen; //adunarea
noului termen
}while(termen_ant-termen>eps && rang+1<nmax); //continuare
daca nici
// una din conditiile de terminare nu s-a indeplinit
//tiparire rezultate
printf("Suma=%e a rezultat din insumarea a %d termeni,\n",
suma,rang+1);
/*
rang+1 termeni pentru ca s-a adunat si cel de rang 0 */
printf("Diferenta ultimilor doi: %e-%e=%e\n",termen_ant,termen,
termen_ant-termen);
getche();
} |

Instructiunea de iesire din ciclu
|
Sintaxa:
break;
Semantica:
Instructiunea
break
determina iesirea fortata din ciclu, adica iesirea din corpul celei mai
apropiate instructiuni while, for,do-while
sau
switch care o contine si trecerea la
executia instructiunii urmatoare.
Observatii:
-
Oricare
dintre aceste instructiuni poate contine mai multe instructiuni break;
-
De obicei
instructiunea break
apare conditionata de un if:
while(expresie){
...
if(exprb)break;
...
} |
for(expresie1;expresie2;expresie3){
...
if(exprb)break;
...
} |
do{
...
if(exprb)break;
...
}while(expresie); |
Instructiunea de selectie
|
Sintaxa:
switch(expresie){
//expresie
- de tip intreg, numita expresie selectoare
case k1:prelucrare1
//k1,k2,...,kn
- etichete de tip intreg, distincte
case k2:prelucrare2
//orice
prelucrare consta din 0 sau mai multe instructiuni
...
case kn:prelucraren
default:prelucrarex
//optional,
corespunde multimii de valori diferite de etichete
}
Semantica:
Se
evalueaza expresie;
daca se gaseste o eticheta avand valoarea egala cu a expresiei, se executa
prelucrarea corespunzatoare acesteia si celelalte, pana la sfarsitul lui
switch;
daca nici o eticheta nu are valoarea expresiei si exista default,
se executa prelucrarex;
altfel, se trece la instructiunea urmatoare.
Observatie:
-
Pentru
a se executa doar prelucrarea corespunzatoare unei etichete, nu si cele
urmatoare, fiecare prelucrare se termina cu instructiunea break:
switch(expresie){
case k1:prelucrare1 break;
case k2:prelucrare2 break;
...
case kn:prelucraren break;
default:prelucrarex
}
Gasiti
secventa echivalenta instructiunii switch,
in care sa se foloseasca doar instructiunea de decizie if-else.
Exemplu:
Urmatorul
program executa operatiile unui calculator de buzunar simplu : adunare,
scadere, inmultire si impartire a doua numere reale. Se preiau linii de
forma :
numar operator numar
si
se afiseaza rezultatul calculului matematic. Secventa calculelor se incheie
cu CTRL/Z.
#include
<stdlib.h>
#include
<stdio.h>
#define
PROMPT ':'
void
main(void){
float a,b,result;
char oper,eroare;
while (putchar(PROMPT),(scanf("%f%c%f",&a,&oper,&b)!=EOF)){
eroare=0;
switch(oper){
case '+': result=a+b; break;
case '-': result=a-b; break;
case '*': result=a*b; break;
case '/': if(b)result=a/b;
else {
puts("*** Impartire la 0 ***");
eroare=1;
}
break;
default : printf("*** Operator ilegal %c ***\n",
oper);
eroare=1;
}//switch
if(!eroare)
printf("rezultatul e %f\n", result);
}//while
}//main |
Instructiunea de revenire din functie
|
Sintaxa:
return;
sau return
expresie;
Semantica:
Se
revine din functia care contine instructiunea, in cea apelanta, la instructiunea
urmatoare apelului; se returneaza valoarea expresiei pentru cazul al doilea.
Quiz
|
Inainte de a trece la Exercitii,
incercati sa gasiti raspunsurile corecte la autotestele de mai jos - puteti
testa secventele, introducandu-le in mici programe pe care sa le rulati:
1.Daca
int
crt; care din secventele de mai jos
tipareste numerele de la 1 la 10?
2.Secventa
de mai jos va tipari pe ecran:
int
i=4;
switch(--i){
case 3:putchar('*');
case 4:putchar('$');
default:putchar('#');
}
Exercitii
|
1.Se
citesc de la tastatura perechi de intregi de forma a n, pana la introducerea
lui CTRL/Z. Sa se determine si sa se tipareasca urmatoarele informatii:
-sa
se tipareasca in bazele 10, 16, 8 valoarea obtinuta prin setarea/stergerea/complementarea
bitului de rang n din a
-numarul
de perechi citite
-media
aritmetica si geometrica a valorilor a
-numarul
de valori a pozitive
-valoarea
minima pentru a
-numarul
de valori a cu bitul de rang 2 setat
-numarul
de valori a care prin impartirea cu 2n conduc la un numar divizibil
cu 3 ( impartirea se face prin deplasare la dreapta ).
Sa
se modifice programul astfel incat citirea perechilor sa se faca atat timp
cat valoarea lui n reprezinta un rang din n ( 0..15 ) - ( vezi aplicatia
rezolvata).
2.Se
citesc de la tastatura valori reale, pana la introducerea lui CTRL/Z.
Sa
se calculeze si sa se afiseze mediile:
-
aritmetica
-
geometrica ( radicalul de ordin n dintr-un numar x se calculeaza prin apelul
functiei pow(x,1.0/n) cu prototipul in math.h )
-
armonica cu relatia n/med_arm=1/val1 + 1/val2 + ... + 1/valn.
3.Sa
se calculeze si afiseze rezistentele echivalente pentru legarea in serie,
respectiv paralel a celor cu valorile reale introduse de la tastatura si
terminate cu CTRL/Z. La introducerea unei valori invalide ( <=0 ) se
semnaleaza eroare si se termina programul.
4.Sa
se afiseze numerele prime dintre doua valori min si max, citite cu validare,
astfel incat min<=max. Analog pentru afisarea tuturor numerol divizibile
cu un numar pozitiv citit..
5.Sa
se afiseze descompunerea in factori primi ( factorii primi si exponentii
) pentru un numar citit.
6.Pentru
doua date citite, in an, luna, zi, sa se afiseze numarul de ani intregi
trecuti.
7.Se
se determine toate patratele perfecte dintre doua valori citite.
8.Sa
se scrie programul care determina daca trei valori reale citite pot fi
laturile unui triunghi, in caz afirmativ, afisandu-i aria calculata cu
formula lui Heron si determinand daca e echilateral, isoscel sau oarecare.
9.Sa
se calculeze valoarea expresiei (n-a)b-n, pentru n variind intre
a si b inclusiv; a si b se citesc, astfel incat sa fie pozitivi si b>a.
Nu se va utiliza functia pow, ci ridicarea la putere se va realiza prin
inmultiri repetate.
10.Sa
se afiseze codurile ASCII ale literelor mari si mici.
11.Se
considera functia: f(x)=(x^2-9)/(x-1), pentru x<1
x, pentru x>=1 si x<=5
1/(x-5), pentru x>5.
Sa
se afiseze valorile functiei f(x) pentru xC[a,b], cu pasul p, numarul punctelor
in care x si f(x) sunt de acelasi
semn
si media aritmetica a valorilor calculate.a, b si p se citesc de la tastatura,
cu validare, astfel incat a<=b.
Copyright
© 2001-2002. Carmen Holotescu
All
rights reserved. Published by Timsoft
|