Sunteți pe pagina 1din 13

7.

FUNCII DEFINITE DE UTILIZATOR

7.1 SCOPUL LUCRRII

Scopul lucrrii este de a prezenta una dintre armele cele mai puternice ale programrii
procedurale, anume aceea a utilizrii, alturi de funciile predefinite din biblioteci, a funciilor
definite de ctre utilizator.
Se exerseaz comparativ transmiterea parametrilor prin valoare i prin referin.
Aplicaiile din exemple i din problemele propuse spre rezolvare fac apel la
variabilele locale i globale

7.2 BREVIAR TEORETIC

Pentru utilizarea funciilor n C++, este necesar cunoaterea urmtoarelor aspecte de


baz:

a) Funciile grupeaz setul de operatori pentru ndeplinirea unei sarcini concrete.


b) Programul principal apeleaz la funcie, adresndu-se la numele ei, dup care
urmeaz paranteze rotunde.
c) Dup terminarea prelucrrii informaiei, majoritatea funciilor ntorc programului
principal valori de tipuri concrete, care pot fi olosite n calcule.
d) Programul principal transmite funciilor parametrii (informaia iniial), inclus n
paranteze rotunde, care urmeaz dup numele funciei.
e) Limbajul C++ folosete prototipuri de funcie pentru determinarea tipului valorii
returnate de ctre funcie, a cantitii si tipurilor parametrilor transmii funciei.

n timpul crerii programului, e necesar s se rezerve fiecare funcie pentru rezolvarea


unei sarcini. Fiecare funcie creat trebuie s primeasc un nume unic.
Ca i n cazul variabilelor, numele unei funcii este un identificator i e de dorit s
corespund cu sensul logic al sarcinei pe care o ndeplinete.

Funciile din C++ se aseamn structural cu funcia principal main().

n faa numelui funciei se indic tipul ei, iar dup numele funciei urmeaz lista
de parametri descrii nuntrul parantezelor rotunde.

Corpul funciei (compus din operatori) este amplasat dup descrierea parametrilor,
ntre acolade.
Sintaxa descrierii unei funcii:

tip_f nume_f (lista parametri) {declarare de variabile; operatori;}

unde

tip_f - tipul funciei sau tipul valorii returnate de funcie,


nume_f - numele funciei.

Dac funcia nu ntoarce valori, tipul ei este void.

1. Transmiterea parametrilor n funcie.

Dac funcia folosete parametri, ei trebuie descrii n cadrul descrierii funciei.


n timpul descrierii parametrelor funciei se indic numelei tipul fiecrui parametru.

tip_parametru nume_parametru;

Dac funcia conine mai muli parametri, ei vor fi descrii mpreun ntre parantezele
rotunde dup numele funciei, desprii prin virgul

tip_funcie nume_funcie (tip_parametru1 nume_parametru1,


tip_parametru2 nume_parametru2
.
tip_parametruN nume_parametruN );

n unele surse de descriere a limbajului de programare C/C++, parametrii ce se


transmit din program n funcie se numesc actuali, iar parametrii ce sunt declarai n antetul
funciei i crora li se atribuie valorile parametrilor actuali, se numesc parametri formali.

n momentul folosirii parametrilor n funcie, este necesar cunoaterea urmtoarelor


aspecte:

- Dac funcia folosete parametri, ea trebuie s indice numele unic i tipul fiecrui
parametru.
- Cnd programul apeleaz funcia, compilatorul atribuie valoarea parametrilor de la stnga la
dreapta
- Valorile transmise din program n funcie, trebuie s coincid ca numr, loc i tip cu
parametrii din funcie.

2. ntoarcerea valorilor din funcie.

Obiectivul oricrei funcii este ndeplinirea unei sarcini concrete. n majoritatea


cazurilor, funciile vor efectua calcule. Dup aceasta, funcia va ntoarce rezultatul fie funciei
din care a fost apelat, fie funciei principale main. n momentul cnd funcia ntoarce o
valoare, trebuie s fie cunoscut tipul ei. Tipul valorii returnate de funcie se indic n
momentul descrierii funciei, nainte de numele ei. Tipul valorii returnate se mai numete i
tipul funciei.
Funciile folosesc operatorul return pentru a ntoarce valori funciilor din care au fost apelate.
Cnd compilatorul ntlnete operatorul return, el ntoarce valoarea dat i ncheie
executarea funciei curente, controlul executrii programului fiind cedat funciei din care a
fost chemat funcia curent. Dac dup operatorul return, n funcie mai exist i ali
operatori, ei vor fi ignorai, funcia terminndu-se odat cu ndeplinirea operatorului return.
Valoarea ntoars de funcie poate fi folosit n orice loc al programului, unde
e posibil folosirea unei valori de tip identic cu valoarea returnat. Cnd funcia ntoarce o
valoare, aceast valoare poate fi atribuit unei variabile de acelai tip, folosind operatorul de
atribuire. Valoarea mai poate fi folosit n cadrul instruciunilor de afiare, n cadrul
instruciunilor de decizie sau a instruciunulor de ciclare.
De asemenea, ea poate fi folosit ca parametru n cadrl apelului altei funcii.

3. Prototipul funciei.

nainte de apelul unei funcii, compilatorul C++ trebuie s cunoasc tipul valorii
returnate, cantitatea i tipul parametrilor folosii de funcie.
Exist ns situaii cnd unele funcii n program snt apelate reciproc. n aceste cazuri,
este posibil situaia cnd o funcie va fi apelat naintea descrierii sale.
n acest caz, se folosesc prototipuri ale funciilor. Prototipul unei funcii este amplasat la
nceputul programului i conine informaia despre tipul valorii returnate, cantitatea i tipul
parametrilor folosii de funcie.
Odat declarat prototipul unei funcii, nainte de a fi nceput corpul programului,
descrierea funciei poate fi fcut dup acolada de nchidere a programului principal.

4. Variabile localei domeniul de vizibilitate.

Apare adeseori necesitatea folosirii n funcii a variabilelor proprii.Variabilele


declarate n cadrul funciei e numesc variabile locale. Numele i valoarea unei variabile
locale sunt cunoscute numai funciei n care ea a fost declarat. Chiar faptul c variabila
local exist este cunoscut numai de ctre funcia n are ea a fostd eclarat. Declararea
variabilelor are loc la nceputul funciei, imediat dup acolada care deschide corpul acesteia.
Numele variabilei locale trebuie s fie unic n funcia n care a fost declarat. O variabilse
numete local, din cauz c este vzut numai din funcia n care a fost descris.

Sintaxa de declarare a unei variabile locale:

tip_f numele_f (lista parametrilor) {tip_vl numele_vl;}

unde:

tip_f - tipul funciei;


nume_f - numele funciei;
tip_vl - tipul variabilei;
numele_vl - numele variabilei;

Principiile de declarare i folosire a unei variabile locale oricrei funcii sunt identice
cu principiile de declarare i utilizare a unei variabile declarate n corpul funciei
principalemain( );
O variabil declarat n corpul funciei main() este i ea local acestei funcii.
n general, tot ceea ce este valabil pentru a fost spus despre variabilele declarate n funcia
main( ) - tipurile, numele, principiile de utilizare .a.- rmne valabil i pentru o
variabil local, din orice alt funcie.

5. Variabile globale

Numim variabil global o variabil pentru care numele i valoarea sunt cunoscute pe
parcursul ntregului program, orice funcie din acest program.
Pentru a crea o variabil global, se folosete declararea ei la nceputul programului,
n afara oricrei funcii. Orice funcie (inclusiv funcia main), care va urma dup aceast
declarare, poate folosi aceast variabil global.

Declararea unei variabile globale:

# include<>
# include<>

# include<>

tip_vg nume_vg;

eventuale declaraii de funcii

void main (void){}

unde tip_vg este tipul variabilei globale, iar nume_vg numele variabilei globale.

Fiind declarat o variabil global, valoarea ei nu numai c e cunoscut oricrei


funcii din program, dar i poate fi i schimbat de ctre oricare dintre funciile prezente
n program.
Cu toate c prezena variabilelor globale n program adaog noi posibiliti, este de
dorit s nu se fac abuz de folosirea lor. Din cauz c orice funcie din program poate
schimba valoarea variabilei globale, este dificil de urmrit toate funciile care ar putea
schimba aceast valoare, ceea ce conduce la un control dificil asupra execuiei programului

6. Conflicte dintre variabile localei globale

n cazul n care un program trebuie s foloseasc o variabil global, poate aprea o


situaie de conflict ntre numele variabilei globale i numele unei variabile locale. n aceste
cazuri, limbajul C++ ofer prioritate variabilei locale.
Dac exist o variabil global cu acelai nume ca o variabila local, compilatorul
consider, c orice apel al variabilei cu acest nume este un apel al variabilei locale.
Exist situaii, cnd apare necesitatea de a se adresa o variabil global care se afl n
conflict cu o variabil local. n acest caz, se poate folosi operatorul global de acces :: .
7.3 EXEMPLE

A. Transmiterea parametrilor prin valoare i prin referin

#include <conio.h>
#include <iostream.h>
#include <math.h>

float f1(int a,int b,int c){


a=a*a;
b=b*b;
c=c*c;
return sqrt(a+b+c);
}

// Varianta 1

float f2(int &a,int &b,int &c){


a=a*a;
b=b*b;
c=c*c;
return sqrt(a+b+c);
}
/*
*/

/*
//Varianta 2

float f2(int *a,int *b,int *c){


*a=*a* *a;
*b=*b* *b;
*c=*c* *c;
return sqrt(*a+*b+*c);
}

*/
void main(){
int x,y,z;
cout<<"Introduceti pe x : "; cin>>x;
cout<<"Introduceti pe y : "; cin>>y;
cout<<"Introduceti pe z : "; cin>>z;
cout<<"Rezultatul aplicarii lui f1 : "<<f1(x,y,z);
cout<<"x="<<x<<endl;
cout<<"y="<<y<<endl;
cout<<"z="<<z<<endl;

// Varianta 1

cout<<"Rezultatul aplicarii lui f2 : "<<f2(x,y,z);

/*
//Varianta 2
cout<<"Rezultatul aplicarii lui f2 : "<<f2(&x,&y,&z);

*/

cout<<"x="<<x<<endl;
cout<<"y="<<y<<endl;
cout<<"z="<<z<<endl;
getch();
}

B. Se nlocuiete fiecare element al unui vector prin oglinditul su

#include <conio.h>
#include <iostream.h>
#include <string.h>

unsigned long int oglinda(unsigned long int n){


unsigned long int m=0;
int c;
while(n){
m=m*10+n%10;
n=n/10;
}
return m;
}
void main(){
clrscr();
unsigned long int v[100];
int n, i;
cout<<"n=? "; cin>>n;
for(i=1; i<=n; i++){
cout<<"v["<<i<<"]=? ";
cin>>v[i];
}
for(i=1; i<=n; i++) cout<<v[i]<<" ";
cout<<endl;
for(i=1; i<=n; i++) v[i]=oglinda(v[i]);
for(i=1; i<=n; i++) cout<<v[i]<<" ";
cout<<endl;
getch();
}

C. Din vectorul v[] se construiete vectorul w[], care conine pe poziia i valoarea 1,
dac v[i] este prim i valoarea 0, n caz contrar

#include <conio.h>
#include <iostream.h>
#include <string.h>
#include <math.h>

int prim(unsigned long int n){


int i;
for(i=2; i<=sqrt(n); i++) if(n%i==0) return 0;
return 1;
}

void main(){
clrscr();
unsigned long int v[100];
int n, i, w[100];
cout<<"n=? "; cin>>n;
for(i=1; i<=n; i++){
cout<<"v["<<i<<"]=? ";
cin>>v[i];
}
for(i=1; i<=n; i++) cout<<v[i]<<" ";
cout<<endl;
for(i=1; i<=n; i++) w[i]=prim(v[i]);
for(i=1; i<=n; i++) cout<<w[i]<<" ";
getch();
}
D. Cmmdc al tuturor elementelor unui vector

#include <conio.h>
#include <iostream.h>

unsigned long int cmmdc(unsigned long int a, unsigned long int b){
if(a==b) return a;
while(a!=b) if(a<b) b=b-a;
else a=a-b;
return a;
}

void main() {
clrscr();
unsigned long int v[100], div;
int n, i;
cout<<"n=? "; cin>>n;
for(i=1; i<=n; i++){
cout<<"v["<<i<<"]=? "; cin>>v[i];
}
div=cmmdc(v[1],v[2]);
for(i=3; i<=n; i++)
div=cmmdc(div,v[i]);
cout<<div;
getch();
}

E. Aflarea unei rdcini unice dintr-un interval

Se pune problema gsirii unei rdcini unice a unei ecuaii de forma f(x) = 0, ntr-un
interval (a,b) dat. Se garanteaz (din considerente externe, care nu au importan n
rezolvarea problemei) c n intervalul dat rdcina exist i este unic. Fr aceast
presupunere, algorimul prezentat nu este valabil.
Se poate observa c, n aceste condiii, semnul funciei f(x) este diferit n punctul a, de
cel al funciei n punctul b (graficul funciei taie axa x o singur dat) => f(a)f(b) < 0.
Atunci, mprind intervalul (a,b) n dou pri egale, obinem un punct m = (a+b)/2,
iar graficul funciei va tia axa x, fie n punctul m (caz n care algoritmul s-a ncheiat), fie n
intervalul (a,m) dac f(a)f(m) < 0, fie n intervalul (m,b) dac f(m)f(b) < 0.
Continum procesul pn cnd obinem o precizie dorit (|f(x)| < ) unde este o
valoare introdus de la tastatur.
#include <conio.h>
#include <iostream.h>
#include <math.h>

float f(float x){


return x*x-3*x+2;
}

void main(){
clrscr();
float a, b, mijloc, epsi, i=0;
cout<<"a=";cin>>a;
cout<<"b=";cin>>b;
cout<<"epsi=";cin>>epsi;
mijloc=(a+b)/2;
cout<<"punctul initial "<<mijloc<<" f(mijloc)=
"<<f(mijloc)<<endl;
while(fabs(f(mijloc))>epsi){
i++;
if(f(a)*f(mijloc)<0) b=mijloc; else a=mijloc;
mijloc=(a+b)/2;
cout<<"iteratia "<<i<<" mijloc="<<mijloc<<"
f(mijloc)="<<f(mijloc)<<endl;
}
cout<<"radacina este "<<mijloc;
getch();
}

F. Maxime i minime pe liniile i coloanele unei matrice

#include <iostream.h>
#include <conio.h>

void maxmin(int v[10],int n,int &maxim,int &minim){


int i;
maxim=v[1];
minim=v[1];
for (i=2;i<=n;i++) {
if (maxim<v[i]) maxim=v[i];
if (minim>v[i]) minim=v[i];
};
};
void main(){

// Maxime si minime in matrice

/* Semnificatia variabilelor:

mxln[] - vectorul maximelor pe linii


mnln[] - vectorul minimelor pe linii
mxcl[] - vectorul maximelor pe coloane
mncl[] - vectorul minimelor pe coloane

mxmxln - maximul din maximele pe linii


mxmnln - maximul din minimele pe linii
mnmxln - minimul din maximele pe linii
mnmnln - minimul din minimele pe linii
mxmxcl - maximul din maximele pe coloane
mxmncl - maximul din minimele pe coloane
mnmxcl - minimul din maximele pe coloane
mnmncl - minimul din minimele pe coloane */
clrscr();

int a[10][10], ajut[10], mxln[10], mnln[10], mxcl[10], mncl[10];


int n, m, i, j,k, mxmxln ,mxmnln, mnmxln, mnmnln, mxmxcl, mxmncl,
mnmxcl, mnmncl;

cout<<"Introduceti numarul de linii : ";


cin>>m;
cout<<"Introduceti numarul de coloane : ";
cin>>n;

cout<<"Introduceti elementele matricii\n\n";


for (i=1;i<=m;i++)
for (j=1;j<=n;j++) {
cout<<"a["<<i<<"]["<<j<<"]=";
cin>>a[i][j];
};
cout<<endl;

for (i=1;i<=m;i++){
for (j=1;j<=n;j++)
cout<<a[i][j]<<" ";
cout<<endl;
};
cout<<endl;
for (i=1;i<=m;i++) {
for (j=1;j<=n;j++) ajut[j]=a[i][j];
maxmin(ajut,n,mxln[i],mnln[i]);
cout<<"linia "<<i<<" : "<<"max="<<mxln[i]<<"
min="<<mnln[i]<<endl;
}
cout<<endl;

maxmin(mxln,m,mxmxln,mnmxln);
cout<<"Maximumul din maximele pe linii este "<<mxmxln<<endl;
cout<<"Minimumul din maximele pe linii este "<<mnmxln<<endl;
maxmin(mnln,m,mxmnln,mnmnln);
cout<<"Maximumul din minimele pe linii este "<<mxmnln<<endl;
cout<<"Minimumul din minimele pe linii este "<<mnmnln<<endl;
cout<<endl<<"Pentru continuare, apasati orice tasta!";
getch();
cout<<endl<<endl;
for (j=1;j<=n;j++) {
for (i=1;i<=m;i++) ajut[i]=a[i][j];
maxmin(ajut,m,mxcl[j],mncl[j]);
cout<<"coloana "<<j<<" : "<<"max="<<mxcl[j]<<"
min="<<mncl[j]<<endl;
}

cout<<endl;
maxmin(mxcl,n,mxmxcl,mnmxcl);
cout<<"Maximumul din maximele pe coloane este "<<mxmxcl<<endl;
cout<<"Minimumul din maximele pe coloane este "<<mnmxcl<<endl;
maxmin(mncl,n,mxmncl,mnmncl);
cout<<"Maximumul din minimele pe coloane este "<<mxmncl<<endl;
cout<<"Minimumul din minimele pe coloane este "<<mnmncl<<endl;
getch();

}
7.4 TEME DE LABORATOR

1. S se realizeze subprogramele prim, invers, i suma, care primesc fiecare. prin


intermediul parametrului n, valoarea unui numr ntreg lung. Subprogramul prim
returneaz valoarea 1, dac numrul n este prim i 0 n caz contrar; subprgramul
invers returneaz oglinditul numrului primit prin intermediul parametrului, iar
subprogramul suma returneaz suma cifrelor numrului primit ca parametru.
Programul principal citeste de la tastatur un numr n, care reprezint numrul de
elemente ale unui vector v, ale crui elemente se vor citi de la tastatur. Cu
ajutorul subprogramelor prim, invers i suma, elementele prime ale vectorului v
se vor nlocui cu oglinditele lor, iar cele care nu sunt prime cu suma cifrelor lor.
Vectorul nou format se va tipri pe monitor.

2. Cu ajutorul subprogramelor prim i invers de la punctul anterior, s se afieze pe


monitor toate numerele prime de dou cifre, care citite invers sunt tot prime.

3. Subprogramul aparcifra are doi parametri: numar un numr ntreg lung; cifra
un numr ntreg de o singur cifr. Programul returneaz numrul de apariii ale
cifrei cifra n numrul numar.
Programul principal citeste de la tastatur un numr n, care reprezint numrul de
elemente ale unui vector v, ale crui elemente se vor citi de la tastatur, i o cifr
c. Cu ajutorul subprogramului aparcifra, elementele vectorului v se vor nlocui
fiecare cu numrul de apariii ale cifrei c n respectivul element. Vectorul nou
format se va tipri pe monitor.

4. Utiliznd subprogramul aparcifra de la punctul anterior, s se calculeze cte cifre


pare are un numr n, citit de la tastatur.

5. Utiliznd subprogramul aparcifra de la punctul anterior, s se calculeze cte cifre


distincte are un numr n, citit de la tastatur

6. Subprogramul elimincifra are doi parametri: numar un numr ntreg lung; cifra
un numr ntreg de o singur cifr. Subprogramul returneaz numrul primit, din
care s-au eliminat toate apariiile cifrei cifra.
Programul principal citeste de la tastatur un numr n, care reprezint numrul de
elemente ale unui vector v, ale crui elemente se vor citi de la tastatur. Programul
va nlocui fiecare element din vectorul v cu numrul obinut prin eliminarea
tuturor cifrelor impare din numr; vectorul nou format se va tipri pe monitor.

7. Cu ajutorul subprogramului prim, de la problema 1, s se calculeze cele mai


apropiate numere prime a i b, cu a < n <b (n citit de la tastatur)
8. S se realizeze subprogramul ordon, care primete ca parametri:
- un vector v de numere ntregi;
- un numr natural n, reprezentnd numrul de elemente ale vectorului v;
Subprogramul returneaz doi vectori, a i b, coninnd vectorul v ordonat cresctor,
respectiv descresctor; vectorii a, b, v NU sunt variabile globale

9. S se realizeze subprogramul doivect, care primete ca parametri:


- un vector v de numere ntregi;
- un numr natural n, reprezentnd numrul de elemente ale vectorului v;
- un vector w de numere ntregi;
- un numr natural m, reprezentnd numrul de elemente ale vectorului w.
Subprogramul returneaz un vector a, cuprinznd elementele comune din vectorii v i
w. Vectorii v, w, i a NU sunt variabile globale

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