Sunteți pe pagina 1din 43

Limbaje de programare

Cuprins
Structura unui program C
Secvențierea
Operații simple de citire/scriere
Operatori relaționali
Operatori logici
Operatorul condițional
Instrucțiuni condiționale
Instrucțiuni de ciclare
Bibliografie selectivă
Structura unui program C
Directive de precompilare #include <stdio.h>
int suma(int x, int y)
Declaratii si definitii de functii { return (x + y);
Functia main }
void afisare_suma(int x, int y)
{ printf("Suma=%d", x + y);
}
int main()
{ int x= 5 , y=7, s;
y = 7;
s = suma(x, y);
printf("Suma este %d\n", s);
afisare_suma(x, y);
return 0;
}
Secvențierea
Instrucțiunile într-o funcție se scriu una după alta (secvențial)
Instrucțiunea compusă: mai multe instrucțiuni între acolade { }
Corpul unei funcții este o instrucțiune compusă (bloc).
{
instrucțiune
...
instrucțiune
}
Secvențierea
Exemplu:
{
int x,y,z;
scanf(”%d %d”,&x,&y);
z=x+y;
printf(”%d+%d= %d”,x,y,z);
}
Instrucțiunea compusă este considerată o singură instrucțiune.
Poate conține și declarații: oriunde (C99)/la început (ANSI C).
Operații simple de citire/scriere
Să ne amintim! #include <stdio.h>
printf:
◦ o funcție standard int main()
◦ nu este instrucțiune sau cuvânt cheie {
◦ este apelată aici cu un parametru șir de caractere printf("Hello world!\n");
◦ constantele șir de caractere sunt incluse între ghilimele " " return 0;
◦ \n este notația pentru caracterul de linie nouă }
Prima linie din program este o directivă de preprocesare,
include fișierul stdio.h cu declarațiile funcțiilor standard de
intrare / ieșire
Declarația = tip, nume, parametri: necesară pentru folosire
Implementarea (codul obiect, compilat): într-o bibliotecă din
care compilatorul ia cele necesare la generarea programului
executabil
Operații simple de citire/scriere
Pentru a tipări valoarea unei expresii, printf #include <stdio.h>
primește două argumente: int sqr (int x)
◦ un șir de caractere (specificator de format): %d {
(pentru întreg, zecimal), %f (pentru real, floating return x * x;
point) }
◦ expresia, al cărei tip trebuie să fie compatibil cu cel int main()
indicat (verificarea cade în sarcina programatorului {
!!!) int a;
scanf primește tot două argumente: printf("dati o valoare (numar intreg) ");
◦ primul argument este la fel cu cel primit de către scanf("%d",&a);
funcția printf printf("%d la patrat = %d\n", a, sqr(a));
◦ al doilea argument este asemănător cu diferența return 0;
ca numele de variabile sunt prefixate de simbolul }
& (ceea ce însemnă adresa variabilei)
Operatori relaționali
Să ne amintim!
Operatorii pot fi: aritmetici, relaţionali, logici, etc.
Operatorii sunt caracterizați de numarul de operanzi pe care se aplică, de clasa de precedență și
de regula de asociativitate.

Clasa de precedenţă Operator Descriere Asociativitate


< Mai mic stânga-dreapta
<= Mai mic sau egal stânga-dreapta
6
> Mai mare stânga-dreapta
>= Mai mare sau egal stânga-dreapta
== Egal stânga-dreapta
7
!= Diferit stânga-dreapta
Operatori relaționali
Atenție: A nu se confunda operatorul de atribuire (=) cu cel relațional de egalitate (==)!
Operatorii relaționali produc expresii care pot fi adevărate sau false și care pot fi folosite drept
condiții în luarea de decizii.
Noțiunea de adevărat/fals este foarte importantă în programare. În multe limbaje de
programare există un tip dedicat pentru aceasta: tipul boolean. În acest caz, tipul boolean are
doar două valori: true (adevărat) și false (fals).
În ANSI C nu dispunem de un tip boolean explicit. Valorile de adevăr sunt exprimate cu ajutorul
tipurilor întregi.
Astfel, o valoare întreagă este interpretată ca:
• true/adevărat dacă este diferită de 0
• false/fals dacă este egală cu 0
Operatori relaționali
Putem atribui, unei variabile de #include <stdio.h>
tip întreg valori rezultate din #include <stdlib.h>
comparații. int pozitiv(int x)
{
Un exemplu este cel alăturat. int rezultat=(x>=0);
Cum se va modifica funcția return rezultat;
pozitiv() pentru a deveni o }
funcție negativ(), care să int main()
returneze 0 pentru numere {
pozitive și o valoare nenulă int x;
pentru cele negative? printf("Dati un numar intreg ");
scanf("%d",&x);
printf("Numarul %d este pozitiv? (0=Nu, altfel =Da), %d \n",x,pozitiv(x));
return 0;
}
Operatori logici
Să ne amintim!

Clasa de precedenţă Operator Descriere Asociativitate

2 ! Negare logică dreapta-stânga


11 && ŞI logic stânga-dreapta
12 || SAU logic stânga-dreapta
Operatori logici
Tabele de adevăr:
Operator Rezultat
Negație
true false
false true

Operator1 Operator2 Rezultat Operator1 Operator2 Rezultat


ȘI SAU
true true true true true true
true false false true false true
false true false false true true
false false false false false false
Operatori logici
Exemple:
e1 && e2 && e3,
dacă e1 falsă ⇒ e1 && e2 && e3 falsă.
e1||e2||e3
dacă e1 adevărată ⇒ e1||e2||e3 adevărată.
În ambele cazuri ar fi inutilă evaluarea e2,e3, etc.
Operatorii && și || se evaluează în scurt-circuit => evaluarea se oprește la prima valoare false
(0) pt && și la prima valoare true (! = 0) pentru ||.
Operatori logici
Exemplu: #include <stdio.h>
#include <stdlib.h>
Dacă x este mai int interval1_10(int x)
mic decât 1, se {
evaluează doar int rezultat=(x>=1)&&(x<=10);
prima expresie return rezultat;
(x>=1), iar (x<=10 }
nu mai este int main()
evaluată. {
int x;
printf("Dati un numar intreg ");
scanf("%d",&x);
printf("Numarul %d se afla in intervaul [1;10]? (0=Nu, altfel =Da), %d \n",x,interval1_10(x));
return 0;
}
Operatorul condițional
Fie funcția modul:
𝑥𝑥, 𝑥𝑥 ≥ 0
abs: Z->Z abs(x)=�
−𝑥𝑥, 𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎
Cu cele îınvățate până acum, nu putem defini această funcție în C.
Valoarea funcției nu e dată de o singură expresie, ci de una din două expresii diferite (x sau -x),
depinzând de o condiție (x ≥ 0)
⇒Limbajul trebuie să ofere o metodă de a decide valoarea luată de o expresie în funcție de
valoarea unei condiții (adevărat/fals).
Operatorul condițional
O variantă de implementare este dată de operatorul condițional:

Clasa de precedenţă Operator Descriere Asociativitate


13 ?: Operator condiţional dreapta-stânga

Expresia conditională în C are sintaxa:


conditie ? expr_true : expr_false
Valoarea expresiei condiționale e dată de:
◦ Condiția e adevărată ⇒ valoarea expresiei expr_true
◦ Condiția e falsă ⇒ valoarea expresiei expr_false
Operatorul condițional
Funcția modul:
𝑥𝑥, 𝑥𝑥 ≥ 0
abs: Z->Z abs(x)=�
−𝑥𝑥, 𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎
Implementare in C, folosind operatorul condițional:
int abs(int x)
{
return x >= 0 ? x : -x; // operator minus unar
}

Observație: Funcția abs există ca funcție standard, declarată în stdlib.h


Instrucțiuni condiționale
Instrucțiunea if:
La fel ca și operatorul condițional permite implementarea
unui bloc de decizie.
Să ne amintim cum se reprezintă:

Ne permite să efectuăm [o serie de] acțiuni diferite în


funcție de rezultatul evaluării unei condiții:
if ( conditie )
instructiune condiție adevarată ;
else instructiune condiție falsă ;
Instrucțiuni condiționale start

Funcția modul:
x
𝑥𝑥, 𝑥𝑥 ≥ 0
abs: Z->Z abs(x)=�
−𝑥𝑥, 𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎𝑎
x>=0
da nu

rezultat=x rezultat=-x

rezultat

stop
Instrucțiuni condiționale start

Implementare in C a funcției modul, folosind instrucțiunii if:


x

int abs(int x)
{ x>=0
if (x >= 0) da nu
return x ;
else return −x ; //atenție la indentare!
} rezultat=x rezultat=-x

rezultat

stop
Instrucțiuni condiționale
Atenție: O funcție de tip non-void trebuie sa returneze o valoare in toate cazurile!
Programul următor va compila (cu avertismente...), dar valoarea returnata de funcție pe ramura
respectivă rămâne nedefinită, poate fi orice!

int bad_abs( int x)


{
if (x >= 0)
return x; // incorect , dar va compila . . .
// si daca x<0 ???
}
int main(void)
{
int a = bad_abs(−7); // ce valoarea va avea a??
return 0;
}
Instrucțiuni condiționale
Fie funcția:
−1, 𝑥𝑥 < 0
sgn: Z->Z sgn(x)=� 0, 𝑥𝑥 = 0
1, 𝑥𝑥 > 0
Nu putem transcrie funcția direct în C folosind operatorul condițional
⇒ trebuie să descompunem decizia asupra valorii lui x
⇒ descompunerea în subprobleme mai mici: principiu foarte important în rezolvarea de
probleme
Instrucțiuni condiționale
Funcția:

−1, 𝑥𝑥 < 0 −1, 𝑥𝑥 < 0


sgn: Z->Z sgn(x)=� 0, 𝑥𝑥 = 0  sgn(x) = �𝑑𝑑𝑑𝑑𝑑𝑑𝑑𝑑 𝑥𝑥(≥ 0) 0, 𝑥𝑥 = 0

1, 𝑥𝑥 > 0 1, 𝑥𝑥 > 0

Implementare in C, folosind operatorul condițional:


int sgn(int x)
{
return x < 0 ? -1
: x == 0 ? 0 : 1;
}
Instrucțiuni condiționale
Funcția:
−1, 𝑥𝑥 < 0
sgn: Z->Z sgn(x)=� 0, 𝑥𝑥 = 0 int sgn(int x)
1, 𝑥𝑥 > 0 {
if (x < 0)
Implementare in C, instructiunea if: return -1;
Implementarea este mai ușor de urmărit față de else
cea în care se folosește operatorul condițional. if (x==0)
return 0;
else
return 1;
}
Instrucțiuni condiționale
Dacă sunt mai multe cazuri posibile (valori constante), instrucțiunea switch este mai potrivită.
switch ( expresie ) //se evalueaza expresia
{ case valoare1 :
instructiuni1 ;
break ; // altfel ar continua cu următoarea instrucțiune
case valoare2 : //se sare la valoarea corespunde
instructiuni1 ;
break ;
default : // nicio valoare nu se potriveste cu celelate cazuri // cazul default poate lipsi
}
int op = 0;
printf("Alegeti o optiune\n");
printf("1. Optiunea 1\n");
printf("2. Optiunea 2\n");
Instrucțiuni condiționale printf("0. Exit\n");
scanf("%d", &op);
switch (op)
switch ( expresie ) //se evalueaza expresia {
{ case valoare1 : case 0:
printf("Ati ales optiunea 0");
instructiuni1 ; break;
case 1:
break ; // altfel ar continua cu următoarea instrucțiune printf("Ati ales optiunea 1");
case valoare2 : //se sare la valoarea corespunde break;
case 2:
instructiuni1 ; printf("Ati ales optiunea 2");
break;
break ; default:
default : // nicio valoare nu se potriveste cu celelate cazuri printf("Ati ales o optiune
invalida");
} }
#include <stdio.h>
#include <math.h> //pentru functia abs
int sgn(int x)
{ int result = 0;
Instrucțiuni condiționale if (x!=0) //nu putem imparti la 0 !
switch (x / abs(x)){
case -1:
Funcția: {
−1, 𝑥𝑥 < 0 result = -1;
break;
sgn: Z->Z sgn(x)=� 0, 𝑥𝑥 = 0
}
1, 𝑥𝑥 > 0
case 1:
O altă variantă de implementare ar putea fi: {
result = 1;
break;
}
}
return result; }
int main()
{ int x;
printf("Dati valoarea numarului : ");
scanf("%d", &x);
printf("sgn(%d) = %d\n",x,sgn(x));
return 0;}
#include <stdint.h>
void pow2(int p)
{ int n2 = 1;
Instrucțiuni condiționale switch (p) {
case 4:
În dreapta este un alt exemplu de utilizare a /* fără break, continuă la următoarea
instrucțiunii switch instrucţiune */
n2 *= 2; //este echivalent cu n2=n2*2;
pow2 implementează o funcție pentru calculul 2p , case 3:
unde p ia valori între 0 și 4: n2 *= 2;
case 2:
Mai jos este apelul funcției: n2 *= 2;
int main() { case 1:
int n; n2 *= 2;
printf("Introduceţi o valoare între 0 si 4:"); case 0:
scanf("%d", &n); printf("2 la puterea %d este %d\n", p, n2);
pow2(n); break;
return 0; default:
} printf("Valoare invalidă\n");
}
}
Instrucțiuni de ciclare
Cum obținem prelucrări repetate ale datelor?
O variantă este utilizarea ciclurilor: control direct al iterațiilor (repetițiilor), se modifică prin
atribuire valorile variabilelor
Ne amintim:
Două tipuri de cicluri:
• cu test inițial (condiția anterioară prelucrării)
• cu test final (condiția după prelucrare)
Instrucțiuni de ciclare
Instrucțiunea while:
Sintaxa: while ( expresie ) instrucțiune
Atenție: parantezele ( și ) sunt obligatorii în jurul expresiei!
Semantica instrucțiunii while:
◦ se evaluează expresia
◦ dacă este adevărată ⇒ se execută instrucțiunea (sau setul de instrucțiuni) apoi se revine la
începutul ciclului, la re-evaluarea expresiei
◦ dacă e falsă ⇒ nu se execută nimic! ⇒ corpul ciclului se execută atât timp cât condiția este
adevărată.
#include <stdio.h>
int sum_n(int n)

Instrucțiuni de ciclare {
int x = 0, cnt = 0, s=0;
while (cnt < n)
Exemplu de calcul start {
pentru suma a n printf("Dati un numar");
numere (citite de la n scanf("%d", &x);
tastatură), folosind //citim numarul si apoi il adunam la suma partiala
s=0
instrucțiunea while: cnt=0 s += x;//sau s=s+x
cnt++;
da }
cnt<n return s;
Citeste
nu x }
s=s+x int main() {
int n;
cnt=cnt+1 printf("Introduceti valoarea pentru n (>=0):");
s scanf("%d", &n);
printf("Suma numerelor citite este %d\n", sum_n(n));
stop return 0;
}
Instrucțiuni de ciclare
Instrucțiunea for:
O altă formă de ciclu cu test inițial.
Sintaxa: for ( expr_initializare ; expr_conditie ; expr_actualizare ) instrucțiune
poate fi rescris cu while astfel:
expr_initializare ; while ( expr_conditie ) expr_actualizare
Observații:
◦ oricare din cele 3 expresii (init., cond., act.) poate lipsi, dar cele 2 ; rămân (putem aveam
for(;;))
◦ daca lipsește expr_conditie ⇒ ciclu infinit
#include <stdio.h>
int sum_n(int n)

Instrucțiuni de ciclare {
int x = 0, cnt, s=0;
for (cnt = 0; cnt < n; cnt++)
Exemplu de calcul pentru suma a n {
numere (citite de la tastatură), folosind printf("Dati un numar");
instrucțiunea for: scanf("%d", &x);
//citim numarul si apoi il adunam la suma partiala
s += x;//sau s=s+x
}
return s;
}
int main() {
int n;
printf("Introduceti valoarea pentru n (>=0) :");
scanf("%d", &n);
printf("Suma numerelor citite este %d\n", sum_n(n));
return 0;
}
Instrucțiuni de ciclare
Instrucțiunea do-while:
◦ Implementează ciclu cu test final.
◦ O folosim dacă știm sigur că un ciclu trebuie executat cel puțin odată.
Sintaxa: do
Instrucțiune while ( expresie ) ;
Semantica instrucțiunii do while:
◦ se execută instrucțiunea (sau setul de instrucțiuni)
◦ se evaluează expresia
◦ dacă e adevărată ⇒ se revine la începutul ciclului, la re-executarea corpului ciclului
◦ dacă e falsă ⇒ nu se mai execută nimic!
#include <stdio.h>
int sum_n(int n)

Instrucțiuni de ciclare {
int x = 0, cnt=0, s=0;
do
Exemplu de calcul pentru suma a n {
numere (citite de la tastatură), folosind printf("Dati un numar");
instrucțiunea do-while: scanf("%d", &x);
//citim numarul si apoi il adunam la suma partiala
Atenție: prima iterație se efectuează s += x; //sau s=s+x
indiferent de valoarea lui cnt, deci cnt++;
programul funcționează doar pentru } while (cnt < n);
valori ale lui n strict pozitive! return s;
}
int main() {
int n;
printf("Introduceti valoarea pentru n (>0):");
scanf("%d", &n);
printf("Suma numerelor citite este %d\n", sum_n(n));
return 0;
}
Instrucțiuni de ciclare
Cum gândim ciclurile?
1. identificăm ce variabile se modifică în fiecare iterație
2. identificăm condiția de ieșire din ciclu
3. avem grijă să actualizăm valoarea variabilei/variabilelor pentru a ne apropia de condiția de
ieșire (altfel ciclul devine infinit!)
Instrucțiuni de ciclare
Instrucțiunea break:
Produce ieșirea din corpul ciclului imediat înconjurător.
O folosim dacă nu dorim să continuăm restul prelucrărilor din ciclu.
Sintaxa: break;
De regulă, ieșirea din ciclu se face condiționat:
if (conditie) break;
#include <stdio.h>
int sum_n(int n)
{

Instrucțiuni de ciclare
int x = 0, cnt=0, s=0;
while (1) //conditie mereu adevarata
//Atentie fara break=>ciclu infinit
Exemplu de calcul pentru suma a n {
numere (citite de la tastatură), folosind if (cnt >= n)
instrucțiunea while si break: break;
printf("Dati un numar");
scanf("%d", &x);
//citim numarul si apoi il adunam la suma partiala
s += x;//sau s=s+x
cnt++;
}
return s;
}
int main() {
int n;
printf("Introduceti valoarea pentru n (>=0):");
scanf("%d", &n);
printf("Suma numerelor citite este %d\n", sum_n(n));
return 0;
}
Instrucțiuni de ciclare
Instrucțiunea continue
Produce ieșirea din iterația curentă a ciclului imediat înconjurător și trecerea la începutul
iterației următoare a acestuia, sărind peste restul instrucțiunilor.
O folosim dacă nu dorim să continuăm restul prelucrărilor din iterația curentă, dar dorim să
continuăm ciclul.
Sintaxa: continue;
De regulă, saltul la iterația următoare se face condiționat:
if (conditie) continue;
#include <stdio.h>
int sum_n(int n)
{

Instrucțiuni de ciclare
int x = 0, cnt=0, s=0;
while (cnt<n)
{
Exemplu de calcul pentru suma printf("Dati un numar");
numerelor pozitive din n numere citite de scanf("%d", &x);
la tastatură, folosind instrucțiunea while //citim numarul si apoi il adunam la suma partiala
si continue: if (x < 0)
continue;
s += x; //sau s=s+x
cnt++;
}
return s;
}
int main() {
int n;
printf("Introduceti valoarea pentru n (>=0):");
scanf("%d", &n);
printf("Suma numerelor citite este %d\n", sum_n(n));
return 0;
}
switch (op)
{
case 1:
Instrucțiuni de ciclare printf("Ati ales optiunea 1\n");
//functie 1
break;
case 2:
Exemplu: Meniu text printf("Ati ales optiunea 2\n");
//functie 1
void meniu(void) break;
{ case 3:
int op; printf("Ati ales optiunea 3\n");
do //functie 1
{ break;
printf("\nMeniu\n\nAlegeti una din case 0:
optiunile urmatoare\n"); return;
printf("1. Optiunea 1\n"); default:
printf("2. Optiunea 2\n"); printf("Optiune invalida\n");
printf("3. Optiunea 3\n"); }
printf("0. Exit\n"); } while (op != 0);
scanf("%d", &op); }
Exerciții
E3_1: Realizați câte un proiect cu exemplele de cod din acest curs și urmăriți cu ajutorul
depanatorului de programe (debugger) execuția programelor linie cu linie.
E3_2: Scrieţi în două moduri diferite câte o funcţie care returnează 1 dacă o valoare număr
natural primită ca parametru reprezintă un an bisect şi returnează 0 în caz contrar.
E3_3: Scrieţi în două moduri diferite câte o funcţie care calculează media numerelor negative din
n numere citite de la tastatură.
Pentru mai multe informații cu privire la subiectele acoperite de acest curs, parcurgeți capitolul
3 (sectiunile 3.1-3.7) din:
◦ Kernighan, B. W., & Ritchie, D. ”The C programming language - Second edition”, 1988
Prentice Hall Software Series
Bibliografie selectivă
◦ Kernighan, B. W., & Ritchie, D. ”The C programming language - Second
edition”, 1988 Prentice Hall Software Series
◦ Minea, M., Limbaje de programare, materiale de curs
http://staff.cs.upt.ro/~marius/curs/lp/index.html
◦ Holotescu, C., Limbaje de programare, materiale de curs
http://labs.cs.upt.ro/~oose/pmwiki.php/LP/Lectures
◦ Iorga,V., Programarea Calculatoarelor, materiale de curs
http://andrei.clubcisco.ro/cursuri/anul-1/semestrul-1/programarea-
calculatoarelor.html

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