Documente Academic
Documente Profesional
Documente Cultură
1. Introducere
Subprogramele sunt pri ale unui program, identificabile prin nume, care se pot activa la cerere prin intermediul acestor nume. Prezena subprogramelor implic funcionarea n strns legtur a dou noiuni: definiia unui subprogram i apelul unui subprogram. Definiia unui subprogram reprezint de fapt descrierea unui proces de calcul cu ajutorul variabilelor virtuale (parametri formali) iar apelul unui subprogram nu este altceva dect execuia procesului de calcul pentru cazuri concrete (cu ajutorul parametrilor reali, (efectivi, actuali) ).
n cazul n care tipul rezultatului este diferit de void, corpul funciei trebuie s conin cel puin o instruciune return. nstruciunea return va specifica valoarea calculat i returnat de funcie care trebuie s fie de acelai tip ca i tip_returnat. Reprezint numele dat funciei de ctre cel ce o definete, pentru a o putea apela. Reprezint o list de declaraii de variabile separate prin virgul. Aceast list poate s fie i vid. Este o instruciune vid sau o instruciune simpl sau o instruciune compus.
Nume_funcie
Lista_parametrilor_formali
Instruciune
parametru efectiv = parametru actual = parametru real = parametru de apel lista parametrilor efectivi = fie vid, fie o expresie sau mai multe desprite prin virgul O funcie care returneaz o valoare poate fi apelat fie printr-o instruciune de apel simpl (cazul funciilor care nu returneaz valori) i n plus poate fi apelat ca operand al unei expresii. n cazul n care funcia se apelaz print-o instruciune de apel simpl, rezultatul funciei se pierde. Cnd funcia se apeleaz ca operand, valoarea returnat va fi utilizat n expresie. La apelul unei funcii, valorile parametrilor efectivi se atribuie parametrilor formali corespunztori. n cazul n care unul din tipul unui paramatru efectiv difer de tipul parametrului formal corespunztor, parametrul efectiv va fi convertit spre parametru formal (dac este posibil, altfel compilatorul genereaz eroare). n momentul n care se ntlnete un apel de funcie, controlul execuiei programul este transferat primei instruciuni din funcie, urmnd a se executa secvenial instruciunile funciei. Revenirea dintr-o funcie se face n unul din urmtoarele cazuri: - dup execuia ultimei instruciuni din corpul funciei - la ntlnirea unei instruciuni return Instruciunea return are formatele: - return ; - return expresie ;
Exemplul 3.1 # include <iostream.h> void f1 () { cout << "abc"; } void main () { clrscr(); f1(); } Se va afisa: Abc Funcia nu returneaz o valoare Funcia nu are parametri Apelul funciei este o instruciune de apel simpl Exemplul 3.2 # include <iostream.h> void f1 (int k) { for (int i=1; i<=k ; i++) cout << "abc"<< " "; } void main () { clrscr(); f1(3); } Se va afia: abc abc abc Funcia nu returneaz o valoare Funcia are un parametru formal de tip int Apelul funciei este o instruciune de apel sinpl i se face cu ajutorul unui parametru actual care este de acelai tip cu tipul parametrului formal corespunztor
Exemplul 3.3 # include <iostream.h> # include <math.h> int prim (int x) { int nr_div=0; for (int i=2; i<=sqrt(x); i++) if (x%i==0) nr_div++; if (nr_div==0) return 1; else return 0; } void main () { int N; cout << "N="; cin >> N; if (prim(N)) cout << "PRIM"; else cout << "NU E PRIM"; } Funcia returneaz o valoare de tip int Funcia are un parametru de tip int Rezultatul funciei este este utilizat n cadrul unei expresii.
Exemplul 3.4 # include <iostream.h> # include <math.h> int prim (int x) { for (int i=2; i<=sqrt(x); i++) if (x%i==0) return 0; return(1); } void main () { int N; cout << "N="; cin >> N; if (prim(N)) cout << "PRIM"; else cout << "NU E PRIM"; }
n cazul n care se ntlnete un divizor a lui x se execut instruciunea return 0. Astfel apelul funciei se ncheie. Dac x este numr prim, instruciunea return 0 nu se execut niciodat i n acest caz, dup terminarea execuiei instruciunii for, se execut instruciunea return 1 (care determin ncheierea execuiei funciei).
n cazul n care tipul returnat de funcie lipsete din definiia funciei, acesta este implicit int i nu void.
Exemplul 3.5 P( ) { cout << " un int"; } void main () { clrscr(); cout << p(); } Compilatorul genereaz WARNING Se va afia un numr ntreg Exemplul 3.6 p( ) { return 25; } void main () { clrscr(); cout << p(); } Se afieaz 25 Exemplul 3.7 void p( ) { cout << "void"; } void main () { clrscr(); cout << p(); } Compilatorul genereaz eroare
APELUL FUNCIEI
5.2.
Variabile locale
La fel cum se declar variabilele n cadrul funciei main, la fel se pot declara varibile n cadrul celorlalte funcii. Aceste variabile se numesc locale i sunt accesibile doar de funcia care le-a declarat. La fel n cadrul unei funcii se pot apela i alte funcii, ca i n main, dac acestea au fost definite naintea eventualului apel sau dac este prezent un prototip de funcie naintea funciei apelante i o definiie de funcie n cadrul programului respectiv sau n fiierele incluse n programului respectiv.
5.3.
Variabile globale
Variabilele globale sunt declarate nafara oricrei funcii i pot sunt vizibile (pot fi utilizate) n tot programul (n programul principal i n subprograme) din momentul declarrii lor.
Exemplul 5.1 # include <iostream.h> int N; void f1() { int x=5; N=10; cout << endl<<N; cout << endl << x; } Exemplul 5.2 # include <iostream.h> int N; void f1() { int x=5; cout << endl << x; P=2 //eroare } int P=9;
4
Exemplul 5.3 # include <iostream.h> int N; void f1(int p) { int x=p; cout << x; } void main ()
{ f1(3); }
N este variabil global. Poate Compilatorul genereaz eroare Se afieaz 3 fi accesat n cadrul oricrei funcii. deoarece funcia main ncearc s N este variabil global. acceseze variabila x care este vizibil x este variabil local, vizibil Poate fi accesat n cadrul oricrei doar n funcia f1(). doar n cadrul funciei f1() funcii. Compilatorul genereaz eroare Se va afia: x este variabil local. deoarece P este accesat n f1() Poate fi accesat doar n cadrul 4 nainte de a fi declarat. funciei f1() 10 p este parametru formal. 5 Poate fi accesat doar n f1().
5.4.
Regula de omonimie
n cazul n care exist o variabil local care are acelai nume cu o variabil global, aceste dou variabile se numesc variabile omonime. Variabilele locale sunt prioritare (ascund) variabilele globale omonime.
Exemplul 5.4 Int N=10; Void f1() { int N=2; cout << N; } void main () { f1(); cout << N; } Variabila N este definit att ca variabil global ct i ca variabil local n f1(). Se va afisa: 2 10 Funcia f1() acioneaz asupra variabilei locale N. Funcia main() acioneaz supra variabilei globale N.
ntrebare. Cum gestioneaz compilatorul cele dou variabile omonime ? Rspuns: Variabilelor globale li se rezerv spaiu de memorare la nceputul execuiei programului, ntr-o zon de memorie numit zon de date. Acest spaiu va fi ocupat pn la ncheierea execuiei programului.
Variabilelor locale li se rezerv spaiu ntr-o zon special de memorie numit stiva. La ncheierea execuiei subprogramului, coninutul stivei este eliberat. Din acest motiv, variabilele globale sun vizibile doar n interiorul subprogramului n care au fost declarate.
Datorit faptului c funcia folosete doar adresa primului element pentru a accesa celelalte elemente ale vectorului, n cadrul prototipului sau antetului funciei este suficient dac se specific faptul c parametrul este un vector, nefiind necesar precizarea numrului de elemente ale vectorului. Exemplul 8.2. # include <iostream.h> void Genereaza (int A[], int &x) { cout << "Nr. de elemente="; cin >> x; for (int i=0; i<x; i++) A[I]=random (20); } void main () { int T[100], N; Genereaza (T, N); For (int i=0; i<N; i++) Cout << T[i]<< " "; }
Funcia modific parametrul actual T prin intermediul parametrului formal A deoarece se relizeaz apelul prin pointer. Funcia modific valoarea parametrului actual N prin intermediul parametrului x deoarece se realizeaz apelul prin referin.
O matrice este gestionat n memoria intern ca o succesiune de elemente. Liniile sunt memorate succesiv. Astfel pentru a reine o matrice este suficient dac se cunosc: adresa de nceput a primului element din matrice i lungimea unei linii (adic numrul de coloane). Astfel la transmiterea unei matrice ntr -o funcie este suficient dac se precizeaz numele matrice respective (adresa de primului element) i dimensiunea unei linii (numrul de coloane). Exemplul 8.3. void Genereaza (int A[][10], int &x, int &y) { cout << "Nr. de linii: "; cin >> x; cout << "Nr. de coloane: "; cin >> y; for (int i=0; i<x; i++) for (int j=0; j<y; j++) A[i][j]=random (20); } void Afiseaza (int A[][10], int x, int y) { for (int i=0; i<x; i++) { for (int j=0; j<y; j++) { cout.width(5); cout << A[i][j]; } cout<<endl; } } void main () { int T[10][10], N, M; Genereaza (T, N, M); Afiseaza (T, N, M); }