Sunteți pe pagina 1din 9

SUBPROGRAME C++

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) ).

2. Structura unui subprogram C++


Un subprogram (funcie) are o definiie i attea apeluri cte sunt necesare.

Definiia unei funcii are forma general:


tip_returnat nume_funcie (lista parametrilor formali) { instruciune; // corpul funciei } Reprezint tipul rezultatului calculat i returnat de funcie i poate fi: int, char, char*, long, float, void, etc.
Tip_returnat

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

3. Apelul unei funcii . Revenirea dintr-o funcie


3.1 Apelul unei funcii care nu returneaz o valoare are forma general:

nume_funcie (lista parametrilor efectivi);

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

4. Prototipul unei funcii


Pentru a apela o funcie, aceasta trebui mai nti definit. Astfel apelul unei funcii trebuie precedat de definiia funciei respective. O a doua posibilitate de apelare a funciei const n scrierea prototipului funciei nainte ca acesta s fie apelat. Prototipul funciei conine informaii asemntoare cu cele din antetul funciei. Pot lipsi numele parametrilor formali (conteaz doar tipul i ordinea acestora), n plus acesa este urmat de ;.
Exemplul 4.1. # include <iostream.h> int max (int, int); void main () { cout << max(10, 20); } int max (int a, int b) { if (a>b) return a; else return b; } PROTOTIPUL FUNIEI

APELUL FUNCIEI

DEFINIIA FUNCIEI antetul funciei si - corpul functie

5. Variabile locale i variabile globale 5.1. Funcia main.


n C, numele de funie main determin prima instruciune pe care o va executa programul. Acesta este unica diferen dintre main i celelalte funcii. Din acest motiv se poate spune c orice se poate face n main se poate face i n celelalte funcii.

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 ()

void main () { N=4; cout << N; f1(); }

void main () { f1(); cout << x; P=7;//corect }

{ 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.

6. Parametri formali i parametri actuali


Parametri formali apar n antetul subprogramului i sunt utilizai de subprogram pentru descrierea abstract a unui proces de calcul . Parametri actuali apar n instruciunea de apelare a uni subprogram i sunt folosii la execuia unui proces de calcul pentru valori concrete. Parametrii formali nu sunt variabile. O variabil este caracterizat de nume, tip, i adres. Legarea unui parametru formal la o adres se realizeaz n timpul execuiei instruciunii de apelare a subprogramului.

7. Apel prin valoare i apel prin referin


Exist dou tipuri de apel al subprogramelor: A. Apel prin valoare B. Apel prin referin 7.1. Apel prin valoare se transmite o copie a parametrului actual. Valorile transmise la apelul unui subprogram sunt memorate n stiv. Datorit faptului c, dup terminarea execuiei unui subprogram, stiva este eliberat, n cazul apelului prin valoare parametrul actual nu se modific (se opereaz asupra unei copii a parametrului efectiv) 7.2. Apel prin referin - se transmite adresa parametrului actual. n cazul apelului prin referin, subprogramul, cunoscnd adresa parametrului actual, acioneaz direct asupra locaiei de memorie indicat de aceasta, modificnd valoarea parametrului actual. n C, implicit apelul este prin valoare. Pentru a specifica un apel prin referin, n lista parametrilor formali, numele parametrului formal va trebui precedat de cuvntul simbolul &.
Exemplul 7.1 void schimba_valoare (int x, int y) { int z=x; x = y; y = z; } void schimba_referinta (int &a, int &b) { int aux=a; a=b; b=aux; } void main () { int M=1, N=5; schimba_valoare(M,N); cout << "M="<<M<< " " << "N="<<N<<endl; schimba_referinta(M,N); cout << "M="<<M<< " " << "N="<<N<<endl; } APEL PRIN VALOARE

APEL PRIN REFERIN

Se va afia: M=1 N=5 M=5 N=1

8. Transmiterea tablourilor unei funcii


n C numele unui tablou reprezint adresa primului element din tablou, celelalte elemente fiind memorate la adresele urmtoare de memorie. Din acest motiv, n cazul transmiterii unui tablou unei funcii se transmite de fapt o adres, realizndu-se un apel numit pointer care determin modificarea parametrului actual. Exemplul 8.1 # include <iostream.h> void Genereaza (int A[100], 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.

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); }

9. TRANSMITEREA IRURILOR DE CARACTERE UNEI FUNCII


Datorit faptului c pentru a memora un ir de caractere compilatorul pstreaz doar adresa de nceput a irului de caractere iar restul caracterelor sunt memorate folosind octeii urmtori pn la ntlnirea unui \0, n cazul unui parametru de tip ir de caractere, funcia primete adresa de nceput a irului, modificnd astfel parametrul actual. Exemplul 9.1. void modifica (char * p) { p[2]='x'; } void afiseaza (char * p) { cout << endl << p; } void main () { char s[20]="abcd"; modifica(s); afiseaza(s); }

10. TRANSMITEREA STRUCTURILOR UNEI FUNCII


Exemplul 10.1. struct persoana { char nume[20]; int varsta; }; void Citeste (persoana &x) { cout << "Numele:"; gets(x.nume); cout << "Varsta:"; cin >>x.varsta; } void Afiseaza (persoana x) { cout << "NUMELE: " << x.nume; cout << endl; cout << "VARSTA: " << x.varsta; } void main () { clrscr(); persoana P; Citeste (P); Afiseaza(P); } Modificarea membrilor structurii necesita apelul prin referin

Pentru a afia o structur este suficient apelul prin valoare

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