3Funcţii 3.1Definirea funcţiilor
Funcţiile se definesc într-un program atunci când un grup de instrucţiuni se utilizează în mai multe locuri din program. Acest grup de instrucţiuni se scrie sub forma unei funcţii ce poate fi apelată oriunde în program. Definiţia unei funcţii este
tip numeFunctie (lista de parametri formali)
{
corpul funcţiei
}
Lista de parametri formali are forma
tip1 arg1, tip2 arg2, …, tipn argn
unde tip1, tip2, …, tipn reprezintă tipurile parametrilor arg1, arg2, …, argn. O parte din parametri sunt variabile ce vor fi prelucrate de funcţie (aceşti parametri se numesc parametri de intrare). O funcţie poate calcula o valoare asociată numelui şi mai multe valori asociate unor parametri (aceşti parametri se numesc parametri de ieşire). Atunci când modificăm un parametru de ieşire, valoarea lui se modifică direct în programul care a apelat funcţia. Parametrii tablouri (vectori, matrice, etc.) sunt parametrii de ieşire. Pentru a defini un parametru scalar de ieşire el trebuie să fie o referinţă. Fie T un tip oarecare. Un parametru referinţă de tipul T se defineşte ca
T& nume
Corpul funcţiei este o instrucţiune compusă formată dintr-o secvenţă de instrucţiuni între acolade “{“ şi “}”. Tipul din linia de definiţie a funcţiei se numeşte tipul funcţiei şi este tipul valorii asociate numelui funcţiei. Dacă o funcţie nu are o valoare asociată numelui, tipul ei este void. Asocierea unei valori calculate numelui funcţiei se face cu instrucţiunea return cu forma următoare
return expresie;
unde expresie este valoarea calculată. Când tipul funcţiei este void, se utilizează instrucţiunea
return;
Apelarea unei funcţii se face utilizând-o ca termen într-o instrucţiune de atribuire
var = numeFuncţie(lista de parametri actuali)
Parametrii de apelare a funcţiei se numesc parametri actuali sau argumente. Parametrii de intrare actuali ai unei funcţii pot fi orice constante, variabile sau expresii. Parametrii actuali de ieşire sunt variabile.
Funcţiile sunt recursive, adică o funcţie se poate apela pe ea însăşi.
Un program constă din una sau mai multe funcţii. Una dintre funcţii are numele main şi execuţia programului începe cu această funcţie.
La întâlnirea unui apel la o funcţie compilatorul trebuie să cunoască tipul şi numărul parametrilor ca să verifice dacă apelarea este corectă. De asemenea compilatorul trebuie să cunoască tipul rezultatului pentru a face convertirile necesare când funcţia este termen într-o expresie. Pentru aceasta se utilizează prototipul (şablonul) funcţie care are forma
tip numeFunctie (tip, tip, …);
unde tipurile sunt cele ale parametrilor formali.
In cazul funcţiilor standard, prototipurile sunt memorate în fişierele antet (header) ce sunt semnalate compilatorului prin directive include.
Putem defini propriile biblioteci cu prototipuri pe care să le semnalăm compilatorului cu directiva include. Numele propriilor biblioteci cu prototipuri sunt scrise în directiva include între ghilimele.
In cazul când o funcţie este definită într-un program putem proceda în două feluri:
-
definiţia funcţiei trebuie să apară înainte de prima ei apelare în alte funcţii,
-
se scrie prototipul funcţiei înainte de prima ei apelare şi definiţia funcţiei poate apare oriunde în program.
3.2Probleme rezolvate
Problema 1. Să se definească o funcţie care să calculeze suma a două numere reale. Şablonul funcţiei va fi
double sum(double a, double b);
Programul este cel de mai jos.
#include
using namespace std;
double sum(double a, double b)
{
return a + b;
}
int main(){
double x, y, z;
cout << "dati doua numere reale" << endl;
cout << "x=";
cin >> x;
cout << "y=";
cin >> y;
z = sum(x, y);
cout << "x+y=" << z << endl;
return 0 ;
}
Rezultatele rulării programului sunt prezentate mai jos.
Problema 2. Să se definească o funcţie care să permute valorile a două variabile întregi. Prototipul funcţiei va fi
void perm(int& i, int& j);
Parametrii funcţiei sunt de ieşire şi ei sunt referinţe. Programul este cel de mai jos.
#include
using namespace std;
void perm(int& i, int& j){
int m;
m = i;
i = j;
j = m;
}
int main(){
int x, y;
cout << "x = "; cin >> x;
cout << "y = "; cin >> y;
perm(x, y);
cout << "dupa permutare, x = "<
Problema 3. Să se definească o funcţie care să calculeze cea mai mare dintre două variabile întregi. Prototipul funcţiei va fi
int max(int x, int y);
Programul este cel de mai jos.
#include
using namespace std;
int max(int x, int y){
if(x >= y)
return x;
else
return y;
}
int main(){
int x, y, z;
cout << "x="; cin >> x;
cout << "y="; cin >> y;
z = max(x, y);
cout << "max(x, y) = " << z << endl;
}
Rezultatele rulării programului sunt prezentate mai jos.
Problema 4. Să se definească o funcţie care să calculeze cel mai mare element al unui vector de numere reale. Şablonul funcţiei va fi:
float max(float a[], int n);
unde :
a – vector de numere reale;
n – dimensiunea vectorului a
Se va rescrie funcţia astfel încât rezultatul să fie asociat unui parametru. Prototipul funcţiei va fi în acest caz
void max(float a[], int n, float& rez);
Soluţia primei cerinţe, când rezultatul este asociat numelui funcţiei:
#include
using namespace std;
float max(float a[], int n) {
int i;
float max_t;
max_t = a[0];
for(i = 1; i < n; i++)
if(max_t < a[i])
max_t = a[i];
return max_t;
}
int main(){
int i,n;
float x[20], x_max;
cout << " calculul maximului a n numere reale" << endl;
cout << "n = "; cin >> n;
for(i = 0; i < n; i++){
cout << "x[" << i << "] = "; cin >> x[i];
}
x_max = max(x,n);
cout<<"max = "<
return 0;
}
Rezultatele rulării programului sunt prezentate mai jos.
Soluţia celei de-a doua cerinţe, când rezultatul este asociat unui parametru:
#include
using namespace std;
void max(float a[], int n, float& rez){
int i;
rez = a[0];
for(i = 1; i < n; i++)
if(rez
rez=a[i];
}
void main(){
int i, n;
float x[20], x_max;
cout << "n = "; cin >> n;
for(i = 0; i < n; i++){
cout << "x[" << i << "] = "; cin >> x[i];
}
max(x, n, x_max);
cout << "max = " << x_max << endl;
}
Problema 5. Să se definească o funcţie care să calculeze valoarea medie şi dispersia unui şir de numere reale. Sablonul funcţiei va fi
float mean(float x[], int n, float& var);
unde :
x – vector cu numere reale;
n – dimensiunea vectorului x;
var – dispersia şirului x
Valoarea medie va fi asociată numelui funcţiei mean.
Se va rescrie funcţia asfel încât valoarea medie şi dispersia să fie asociate unor parametri. Şablonul funcţiei va fi
void mean(float x[], int n, float& m, float& var);
Indicaţie. Valoarea medie a şirului x este dată de formula . Dispersia şirului x este dată de formula .
Soluţia primei cerinţe, când media este asociată numelui funcţiei.
#include
using namespace std;
float mean(float x[], int n, float& var){
float s, m;
s = x[0];
for(int i = 1; i < n; i++)
s = s + x[i];
m = s / n;
s = 0;
for(int i = 0; i < n; i++)
s = s + (x[i] - m) * (x[i] - m);
var = s / (n - 1);
return m;
}
int main(){
int n;
float x[20], medie, dispersie;
cout << " media si dispersia a n numere naturale" << endl;
cout << "n = "; cin >> n;
for(int i = 0; i < n; i++){
cout << "x[" << i << "] = "; cin >> x[i];
}
medie = mean(x, n, dispersie);
cout<<"media = "<< medie <<" dispersia = "<
return 0 ;
}
Rezultatele rulării programului sunt prezentate în caseta text.
Soluţia celei de-a doua cerinţe, când media este asociată unui parametru.
#include
using namespace std;
void mean(float x[], int n, float& m, float& var){
float s;
s=x[0];
for(int i = 1; i < n; i++)
s = s + x[i];
m =s / n;
s = 0;
for(int i = 0;i < n; i++)
s = s + (x[i] - m) * (x[i] - m);
var = s / (n - 1);
}
int main(){
int n;
float x[20],medie=0,dispersie=0;
cout << " media si dispersia a n numere naturale" << endl;
cout<<"n = "; cin >> n;
for(int i = 0; i < n; i++){
cout<<"x[" << i << "] = "; cin >> x[i];
}
mean(x, n, medie, dispersie);
cout<<"media = " << medie <<" dispersia = " << dispersie;
return 0 ;
}
Problema 6. Să se definească o funcţie care să verifice dacă un an este bisect. Prototipul funcţiei va fi
bool bisect(int an);
Anii bisecţi sunt divizibili cu 4. Anii divizibili cu 100 nu sunt bisecţi cu excepţia că anii divizibili cu 400 sunt bisecţi.
Exemplu. Anul 1992 este bisect, anul 1900 nu este bisect, anul 2000 este bisect.
Rezultatul funcţiei bisect este de tipul bool. Valorile acestui tip sunt afişare cu manipulatorul boolalpha.
Programul este următorul.
#include
using namespace std;
bool bisect(int an){
if(an % 400 == 0)
return true;
if(an % 100 == 0)
return false;
if(an % 4 == 0)
return true;
else
return false;
}
int main(){
cout << "anul 1992 este bisect ? " << boolalpha << bisect(1992) << endl;
cout << "anul 1900 este bisect ? " << boolalpha << bisect(1900) << endl;
cout << "anul 2000 este bisect ? " << boolalpha << bisect(2000) << endl;
cout << "anul 2007 este bisect ? " << boolalpha << bisect(2007) << endl;
return 0;
}
Rezultatele rulării programului sunt prezentate mai jos.
Problema 7. Să se definească o funcţie generică pentru calculul valorii minime a unui şir de numere. Prototipul funcţiei va fi
template
T minval(T x[], int n);
Se va utiliza funcţia scrisă pentru calculul minimului unor şiruri de valori de tip float, int sau double. Programul este următorul.
#include
using namespace std;
template
T minval(T a[], int n) {
T val = a[0];
int i;
for(i = 1; i < n; i++){
if(val > a[i])
val = a[i];}
return val;
}
int main(){
int i,n;
int xi[20], xi_min;
double xd[20], xd_min;
cout<<"n = "; cin>>n;
cout << "minimul a " << n << " numere intregi" << endl;
for(i=0; i < n; i++){
cout << "dati xi[" << i << "] : "; cin >> xi[i];
}
xi_min=minval(xi, n);
cout << "min intreg = " << xi_min << endl;
cout << "minimul a " << n << " numere reale" << endl;
for(i = 0; i < n; i++){
cout << "dati xd[" << i << "] : "; cin >> xd[i];
}
xd_min=minval(xd, n);
cout << "min doubl e= " << xd_min << endl;
return 0 ;
}
Rezultatele rulării programului sunt cele de mai jos.
Problema 8. Să se calculeze valoarea aproximativă a funcţei:
a) Se vor aduna primii 50 de termeni.
b) Se vor aduna termeni până când termenul următor adăugat este mai mic în modul decât . Se va calcula suma pentru x = 1, x = 2, x = -3, x = 10, x = 20 şi x = -30. Se va afişa şi valoarea calculată cu funcţia de bibliotecă sin(x). Se vor explica rezultatele. Termenii seriei, notaţi t1, t3, etc., sunt următorii: , .
Programul este următorul.
#include
using namespace std;
#include
#include
float sin_100(float x){
// functia aduna primii 100 de termeni
float s,t;
int i;
s = x; t = x;
for(i = 3; i <= 200; i = i + 2){
t = -t * x * x / i / (i-1);
s = s + t;
}
return(s);
}
float sin_prec(float x){
// functia aduna termeni pana la primul termen in modul < 1e-5
float s,t;
int i=3;
s = x; t = x;
while(fabs(t) > 1e-5){
t = -t * x * x / i / (i-1);
s = s + t;
i = i + 2;
}
return(s);
}
int main(){
float x[6] = {1, 2, -3, 10, 20, -30};
cout << "sin(x) calculat cu : " << endl
<< "1) functia standard sin(x) " << endl
<< "2) ca suma a primilor 100 termeni " << endl
<< "3) cu precizia 1e-5" << endl;
cout << setw(6) << "x" << " " << setw(10)
<< "sin(x)" << setw(12)
<< "sin_100" << setw(12) << "sin_p" << endl;
for (int i = 0; i < 6; i++)
{
cout << setw(6)<< x[i] << " " << setw(10) << sin(x[i]) << " "
<< setw(10) << sin_100(x[i]) << " "
<< setw(10) << sin_prec(x[i]) << endl;
}
return 0;
}
Rezultatele rulării programului sunt cele de mai jos.
Dostları ilə paylaş: |