Sunteți pe pagina 1din 7

PCLP I Laboratorul 10

Asist.drd.ing. Ana-Maria SUDUC

Laboratorul 10
Funcţii

1. Noţiuni teoretice
1.1. Forma generală a unei funcţii
Un program conţine una sau mai multe funcţii. Fiecare funcţie are un nume. Numele funcţiei
principale este main, iar numele celorlalte funcţii sunt definite de utilizator.
Forma generală a unei funcţii este:
specificator_de_tip nume_functie (lista_parametri)
{
corpul functiei
}
Specificator_de_tip indică tipul de date returnat de funcţie. O funcţie poate returna orice tip de date,
cu excepţia tablourilor. Lista_parametri este o listă de nume de variabile şi a tipurilor asociate acestora,
separate prin virgulă, care primesc valorile argumentelor la apelul funcţiei. Unei funcţii îi pot lipsi
parametrii, caz în care lista de parametri este vidă. Totuşi, chiar dacă funcţia nu are parametri, parantezele
sunt necesare.
În cazul declaraţiilor de variabile, mai multe variabile pot fi declarate ca fiind de acelaşi tip folosind
o listă de nume de variabile, separate prin virgulă. Spre deosebire de acestea, toţi parametrii unei funcţii
trebuie declaraţi individual, fiecare declaraţie trebuind să conţină numele şi tipul parametrului. Ca atare,
lista de declarare a parametrilor unei funcţii are forma:
f(tip numevar1, tip numevar2,..., tip numevarN)
1.2. Regulile de competenţă ale unei funcţii
Regulile de competenţă ale unui limbaj sunt acele reguli care controlează dacă un fragment de
program are cunoştinţă sau acces la un alt fragment de program sau de date.
În C/C++, fiecare funcţie reprezintă un bloc de cod distinct. Codul unei funcţii este propriu acelei
funcţii şi nu poate fi accesat de nici o altă instrucţiune conţinută într-o altă funcţie, cu excepţia cazului când
este apelată funcţia. Codul care reprezintă corpul unei funcţii este ascuns faţă de restul programului şi, cu
excepţia cazului în care foloseşte date sau variabile globale, nu poate afecta şi nu poate fi afectat de către
alte componente ale programului.
În C/C++, toate funcţiile au acelaşi nivel al domeniului de acţiune, adică nu se poate defini o funcţie
în interiorul altei funcţii. Iată de ce C/C++ nu este, din punct de vedere tehnic, un limbaj structurat pe
blocuri.
1.3. Argumentele unei funcţii
Dacă o funcţie urmează să folosească argumente, trebuie să declare variabile care să accepte valorile
argumentelor. Aceste variabile se numesc parametrii formali ai funcţiei. Aceştia se comportă ca orice altă
variabilă locală în interiorul funcţiei, fiind creaţi la intrarea în funcţie şi distruşi la ieşire. După cum o arată
funcţia care urmează, declaraţiile parametrilor survin după numele funcţiei:
/* Returnează 1 dacă c aparţine şirului s; 0 în caz contrar.*/
int este_in(char *s, char c)
{
while (*s)

1
PCLP I Laboratorul 10
Asist.drd.ing. Ana-Maria SUDUC

if(*s==c) return 1;
else s++;
return 0;
}
Funcţia este_in() are doi parametri, anume s şi c. Această funcţie dă rezultatul 1 dacă caracterul c
este inclus în şirul s şi 0 în caz contrar.
Trebuie să vă asiguraţi că argumentele folosite la apelul unei funcţii sunt compatibile cu tipul
parametrilor acesteia. Dacă tipurile sunt incompatibile, compilatorul nu va emite neapărat un mesaj de
eroare, dar pot apărea rezultate neaşteptate.
1.4. Apelul funcţiilor folosind tablouri
Când un tablou este folosit ca argument al unei funcţii, se transferă numai adresa tabloului, şi nu o
copie a întregului tablou. La apelul unei funcţii cu numele unui tablou, este transmis funcţiei un pointer al
primului element din tablou. Aceasta înseamnă că declararea parametrului trebuie să fie compatibilă cu
tipul pointerului. Există trei modalităţi de a declara un parametru care urmează să primească un pointer
tablou:
- declararea unui tablou;
void afiseaza(int num[10])
- declararea unui tablou nedimensionat;
void afiseaza(int num[])
- declararea unui pointer.
void afiseaza(int *num)
Prima aplicaţie de la punctual 2 reprezintă un exemplu pentru prima modalitate, iar a doua aplicaţie
un exemplu pentru cea de-a treia modalitate.
1.5. Revenirea dintr-o funcţie
Revenirea dintr-o funcţie se poate realiza în două moduri:
- după execuţia ultimei instrucţiuni din corpul funcţiei;
- la întâlnirea instrucţiunii return.
Instrucţiunea return este instrucţiunea de revenire din funcţie. Ea are formatele:
- return
- return expresie
Formatul al doilea se foloseşte în corpul unei funcţii care returnează o valoare la revenirea din ea.
Valoarea expresiei din instrucţiunea return este chiar valoarea returnată de funcţie.
În cazul în care tipul acestei expresii diferă de tipul din antet, valoarea expresiei se converteşte
automat spre tipul din antet, înainte de a reveni din funcţie. Se foloseşte revenirea din funcţie fără
instrucţiunea return sau cu ajutorul instrucţiunii return fără a fi urmată de o expresie atunci când funcţia nu
returnează nici o valoare.

1.6. Funcţia main()


Funcţia main() returnează un întreg în urma procesului de apel, care în general este sistemul de
operare. Returnarea unei valori din main() este echivalentul apelării funcţiei exit() folosind aceeaşi valoare.
Dacă main() nu returnează în mod explicit nici o valoare, atunci valoarea transmisă procesului de apel este
nedefinită din punct de vedere tehnic. În practică, majoritatea compilatoarelor de C/C++ returnează automat
valoarea 0.

2
PCLP I Laboratorul 10
Asist.drd.ing. Ana-Maria SUDUC

Dacă main() nu returnează nici o valoare, poate fi declarată ca fiind de tip void. Unele compilatoare
afişează un avertisment dacă o funcţie nu este declarată de tip void şi nu returnează nici o valoare.
1.7. Prototipizarea funcţiilor
Prototipizarea funcţiei este una dintre îmbunătăţirile majore aduse funcţiilor C++. Prototipul funcţiei
transmite compilatorului detalii despre funcţie: numărul şi tipul argumentelor şi tipul valorilor returnate.
Prototipul funcţiei este o instrucţiune declarativă şi are următoarea formă:
tipul_rezultatului numele_funcţiei (lista_argumente)
Exemplu:
float volum(float a, float b, float c);
1.8. Supraîncărcarea funcţiilor
Supraîncărcarea (supradefinirea) reprezintă posibilitatea de a atribui unui simbol mai multe
semnificații, care pot fi deduse în funcție de context. Limbajul C++ permite supraîncărcarea (overloading)
funcțiilor, adică existenţa mai multor funcţii cu acelaşi nume. Când compilatorul întâlneşte un apel la o
funcţie supraîncărcată, va determina care funcţie va fi apelată prin examinarea numărului şi tipului
argumentelor.
1.9. Transmiterea parametrilor
Transmiterea parametrilor efectivi către o funcţie se poate face prin valoare şi prin referinţă. În
exemplele din laboratoarele anterioare, argumentele erau transmise funcţiilor prin valoare. Acest lucru
înseamnă că la apelul funcţiei cu o serie de parametri, către funcţie au fost transmise copii ale valorilor
acestor parametri (nu variabilele în sine). Spre exemplu, dacă avem o funcţie suma care adună două numere
şi facem apel la această funcţie conform exemplului următor:
int suma (int a, int b)
{
return a+b;
}
void main()
{
int x=4, y=76, z;
z=suma(x,y);
}
către funcţia suma au fost transmise valorile variabilelor x şi y (4 şi 76), nu variabilele în sine.
În acest caz, la apelul funcţiei suma, valoarea variabilelor locale (parametrii formali) a şi b devin 4,
respectiv 76, dar nicio modificare ale valorilor celor două variabile a şi b nu modifică valorile variabilelor x
şi y, deoarece nu variabilele x şi y sau fost transmise funcţiei ci doar copii ale valorilor acestora în
momentul apelului.
În unele cazuri este necesară manipularea valorii unei variabile externe în interiorul unei funcţii.
Acest lucru se poate obţine prin transmiterea argumentelor funcţiei prin referinţă, ca în exemplul următor:
#include <iostream>
using namespace std;

void dublare (int& a, int& b, int& c)


{
a*=2;
b*=2;
c*=2;

3
PCLP I Laboratorul 10
Asist.drd.ing. Ana-Maria SUDUC

void main ()
{
int x=1, y=3, z=7;
dublare (x, y, z);
cout << "x=" << x << ", y=" << y << ", z=" << z;
}
În exemplul dat se observă că fiecare parametru formal este precedat de semnul ampersand (&).
Acest semn indică faptul că argumentul corespondent va fi transmis prin referinţă şi nu prin valoare. Când o
variabilă este transmisă prin referinţă, nu se transmite o copie a acesteia ci chiar variabila în sine şi orice
modificare făcută asupra variabilelor locale va avea un efect asupra variabilelor corespondente transmise ca
argumente ale funcţiei apelate.
1.10. Parametri cu valori implicite
La declararea unei funcţii se poate specifica o valoare implicită pentru fiecare dintre parametri.
Această valoare va fi utilizată atunci când argumentul corespondent rămâne necompletat la apelul funcţiei.
La apelul funcţiei, dacă argumentul corespondent lipseşte, se utilizează valoarea implicită. Dacă pentru
parametrul care are o valoare implicită se transmite un argument, atunci valoarea implicită este ignorată.
Exemplu:
#include <iostream>
using namespace std;

int inmultire (int a, int b=1)


{
return (a*b);
}

void main ()
{
cout << inmultire (12)<<endl;
cout << inmultire (20,4)<<endl;
}
În exemplul anterior, la primul apel al funcţiei inmultire se va obţine rezultatul 12 (12*1 – se
foloseşte valoarea implicită a lui b), iar la cel de-al doilea apel se va obţine 80 (20*4 – valoarea implicită a
lui b este ignorată).

2. Aplicaţii
2.1.Lansaţi în execuţie aplicaţia Visual C++ 2010 Express Edition:
Din meniul Start-> Programs-> Microsoft Visual Studio 2010 Express, executaţi clic pe opţiunea
Microsoft Visual C++ 2010 Express.
2.2. Creaţi un nou proiect, Proiect10 şi un nou fişier File1.cpp:
a) Din meniul File->New, alegeţi opţiunea Project;
b) În fereastra New Project selectaţi opţiunea Win32 şi verificaţi să fie selectat Win32 Console
Application;
c) În câmpul Name introduceţi Proiect10 şi apăsaţi OK;
d) În fereastra deschisă apăsaţi Next şi apoi selectaţi opţiunea Empty Project şi apăsaţi Finish;
e) În secţiunea Solution Explorer executaţi clic dreapta pe directorul Source File şi alegeţi opţiunea
New-> Item;
f) În fereastra Add New Item selectaţi categoria Code şi verificaţi să fie selectată opţiunea C++
File (.cpp);
g) În câmpul Name tastaţi numele File1 şi apăsaţi Add.

4
PCLP I Laboratorul 10
Asist.drd.ing. Ana-Maria SUDUC

2.3. În fişierul File1.cpp introduceţi şi testaţi următorul program care calculează şi afişează suma a două
numere:
#include <iostream>
using namespace std;
int sum(int a, int b); /*prototipul functiei; a si b sunt parametrii formali ai
functiei. Numele parametrilor formali pot lipsi*/

void main ()
{
int r;
r=sum(17,23); //17 si 23 sunt argumentele functiei
cout<<"Valoarea lui r este: "<<r<<endl;
int x,y;
x=17;
y=23;
cout<<"Suma variabilelor x si y este: "<<sum(x,y)<<endl;

}
int sum(int a, int b) //definitia functiei
{
return a+b;
}
a) Tastaţi programul dat, respectând liniile de cod;
b) Compilaţi programul executând clic dreapta pe numele fişierului din secţiunea Solution Explorer
şi executând clic pe opţiunea Compile sau executând combinaţia de taste Ctrl+F7;
c) Corectaţi eventualele erori semnalate în secţiunea Output;
d) După rezolvarea eventualelor erori, rulaţi programul selectând, din meniul Debug, opţiunea Start
Without Debugging sau executând combinaţia de taste Ctrl+F5.
2.4. Modificaţi programul anterior astfel încât valorile lui x şi y să fie citite de la tastatură.
2.5. Scrieţi un program care conţine funcţii de calcul a celor patru operaţii de bază: adunare, scădere,
înmulţire şi împărţire. Apelaţi cele patru funcţii definite cu argumente citite de la tastatură.
2.6. Testaţi programul următor:
#include <iostream>
using namespace std;
void afiseaza(char *n, int v);

void main ()
{
char nume[15];
int varsta;
cout << "Introduceti numele: ";
cin >> nume;
cout << "Introduceti varsta: ";
cin >> varsta;
afiseaza(nume, varsta);
}
void afiseaza (char *n, int v)
{
cout << "Numele tau este " <<n<< " si ai " << v << " de ani."<<endl;
}
2.7. Următorul program afişează elementele unui tablou folosind o funcţie, afisează:
#include <iostream>
using namespace std;

void afiseaza(int x[10]);

void main(void)

5
PCLP I Laboratorul 10
Asist.drd.ing. Ana-Maria SUDUC

{
int t[10],i;
for (i=0; i<10; ++i)
t[i]=i;
afiseaza(t);
}
void afiseaza (int x[10])
{
int i;
for (i=0; i<10; i++)
cout<<x[i]<<' ';
}
2.8. Modificaţi programul anterior astfel încât să conţină un tablou unidimensional de numere întregi,
a[20], cu n elemente a căror valori sunt citite de la tastatură. Afişaţi acest tablou cu ajutorul funcţiei
afiseaza care a fost modificată în prealabil.
2.9. Adăugaţi încă un vector de numere întregi, b[20], cu m elemente a căror valori sunt citite de la
tastatură. Afişaţi cele m elemente cu ajutorul funcţiei afisează.
2.10. Testaţi următorul program care transformă un şir de caractere în majuscule.
#include <iostream>
using namespace std;

void maj(char *sir);

void main (void)


{
char s[80];
cout<<"Introduceti un sir de caractere: ";
cin.getline(s,80);
maj(s);
}
/* Afiseaza continutul unui sir cu majuscule*/
void maj(char *sir)
{
int t;
char ch;
for (t=0; sir[t]; ++t)
{
ch = toupper(sir[t]);
cout<<ch;
}
}
2.11. Să se scrie o funcţie care calculează valoarea minimă a două numere. Apelaţi această funcţie
pentru a calcula minimum dintre a şi b şi apoi dintre c şi d, unde a, b, c şi d sunt patru numere citite
de la tastatură.
2.12. Să se scrie un program care conţine o funcţie ce calculează media aritmetică dintre minimul
şi maximul unui şir de numere dintr-un tablou unidimensional de întregi.
2.13. Să se scrie un program care să realizeze transformări ale temperaturii din grade Celsius in
grade Fahrenheit sau invers. (unde Tf = (9/5)*Tc+32 şi Tc = (5/9)*(Tf-32))
2.14. Să se scrie o funcţie care calculează volumul unui cub.
2.15. Testaţi următorul program care defineşte două funcţii cu acelaşi nume, suma:
#include <iostream>
using namespace std;

int suma (int x, int y);


float suma(float a, float b, float c);

6
PCLP I Laboratorul 10
Asist.drd.ing. Ana-Maria SUDUC

void main()
{
int x,y;
float a,b,c;
cout<<"x=";
cin>>x;
cout<<"y=";
cin>>y;
cout<<x<<"+"<<y<<"="<<suma(x,y)<<endl;
cout<<"a=";
cin>>a;
cout<<"b=";
cin>>b;
cout<<"c=";
cin>>c;
cout<<a<<"+"<<b<<"+"<<c<<"="<<suma(a,b,c)<<endl;
}
int suma (int x, int y)
{
return x+y;
}
float suma(float a, float b, float c)
{
return a+b+c;
}
2.16. Testaţi exemplele furnizate în partea de teorie.
2.17. Testaţi programul următor:
#include <iostream>
using namespace std;

int volume(int);
double volume (double, int);
long volume (long, int, int);

void main()
{
cout << volume(10) << endl;
cout << volume(2.5, 8) << endl;
cout << volume(100L, 75, 15) << endl;
}
int volume(int s) // cub
{
return(s*s*s);
}
double volume(double r, int h) // cilindru
{
return(3.14519*r*r*h);
}
long volume(long L, int l, int h) // paralelipiped
{
return(L*l*h);
}
2.18. Scrieţi un program care creează un calculator cu 4 operaţii. Fiecare dintre cele 4 operaţii se
va realiza prin intermediul unei funcţii.
2.19. Scrieţi câte un program care să exemplifice: supraîncărcarea funcţiilor în C++, apelul
funcţiilor prin referinţă, funcţii cu parametri cu valori implicite.

Referinţe
http://www.cplusplus.com/doc/tutorial/functions2/