Sunteți pe pagina 1din 8

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
while(1)
instructiune
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.

S-ar putea să vă placă și