Tip_returnat |
Reprezintă tipul rezultatului calculat şi returnat de funcţie şi poate fi: int, char, char*, long, float, void, etc. În cazul în care tipul rezultatului este diferit de void, corpul funcţiei trebuie să conţină cel puţin o instrucţiune return. Înstrucţiunea return va specifica valoarea calculată şi returnată de funcţie care trebuie să fie de acelaşi tip ca şi tip_returnat. |
Nume_funcţie |
Reprezintă numele dat funcţiei de către cel ce o defineşte, pentru a o putea apela. |
Lista_parametrilor_formali |
Reprezintă o listă de declaraţii de variabile separate prin virgulă. Această listă poate să fie şi vidă. |
Instrucţiune |
Este o instrucţiune vidă, simplă sau compusă. |
Exemplul 3.1 |
Exemplul 3.2 |
void f1 () { cout << "abc"; } int main () { f1(); } |
#include using namespace std; void f1 (int k) { for (int i=1; i<=k ; i++) cout << "abc"<< " "; } int main () { f1(5); } |
Se va afisa:abc |
Se va afişa:abc abc abc abc abc |
Funcţia nu returnează o valoareFuncţia nu are parametriApelul funcţiei este o instrucţiune de apel simplă |
Funcţia nu returnează o valoareFuncţia are un parametru formal de tip intApelul funcţiei este o instrucţiune de apel simplă şi se face cu ajutorul unui parametru actual care este de acelaşi tip cu tipul parametrului formal corespunzător |
Exemplul 3.3 |
Exemplul 3.4 |
#include using namespace std; int prim (int x) {int nr_div; nr_div=0; for (int i=2; i<=x/2; i++) if (x%i==0) nr_div++; if (nr_div==0) return 1; else return 0; } int main () {int N; cout << "N="; cin >> N; if (prim(N)) cout << "PRIM"; else cout << "NU E PRIM"; } |
include using namespace std; int prim (int x) {int i; for ( i=2; i<=x/2; i++) if (x%i==0) return 0; return 1; } int main () {int N; cout << "N="; cin >> N; if (prim(N)) cout << "PRIM"; else cout << "NU E PRIM"; } |
Funcţia returnează o valoare de tip int Funcţia are un parametru formal de tip int Rezultatul funcţiei este este utilizat în cadrul unei expresii. |
În cazul în care se întâlneşte un divizor a lui x se execută instrucţiunea return 0. Astfel apelul funcţiei se încheie. Dacă x este număr prim, instrucţiunea return 0 nu se execută niciodată şi în acest caz, după terminarea execuţiei instrucţiunii for, se execută instrucţiunea return 1 (care determină încheierea execuţiei funcţiei). |
OBS: În cazul în care tipul returnat de funcţie lipseşte din definiţia funcţiei, acesta este implicit
int şi nu void.
Exemplul 3.5 |
Exemplul 3.6 |
Exemplul 3.7 |
#include using namespace std; p( ) { cout << " abcd"; } int main () { cout << p(); } |
#include using namespace std; p( ) { return 25; } int main () { cout << p( ); } |
#include using namespace std; void p( ) { cout << "void"; } int main () { cout << p(); } |
Compilatorul generează eroare deoarece lipseste tipul returnat de functie |
Compilatorul generează eroare deoarece lipseste tipul returnat de functie |
Compilatorul generează eroare deoarece o functie cu tipul returnatvoidnu se poate apela in cadrul unei functii, in cazul de fata cout |
#include using namespace std; int p( ) { return 25; } int main () { cout << p( ); } |
#include using namespace std; void p( ) { cout << "abcd"; } int main () { p(); } |
|
Se afişează 25 |
Se afişează abcd |
# include using namespace std; int max (int, int); int main () { cout << max(10, 20); } int max (int a, int b) { if (a>b) return a; else return b; } |
PROTOTIPUL FUNŢIEI APELUL FUNCŢIEI DEFINIŢIA FUNCŢIEI antetul funcţiei corpul functiei |
5. Variabile locale şi variabile globale
5.1 . Funcţia main
În C++ funcţia main determină prima instrucţiune pe care o va executa programul. Aceasta este unica diferenţă dintre main şi celelalte funcţii. Din acest motiv se poate spune că “orice se poate face în main se poate face şi în celelalte funcţii”.
5.2. Variabile locale
La fel cum se declară variabilele în cadrul funcţiei main, la fel se pot declara varibile si în cadrul celorlalte funcţii. Aceste variabile se numesc locale şi sunt accesibile doar in funcţia in care au fost declarate.
In cadrul unei funcţii se pot apela şi alte funcţii, cu conditia ca acestea sa fi fost definite înaintea eventualului apel sau este prezent un prototip de funcţie înaintea funcţiei apelate
5.3. Variabile globale
Variabilele globale
sunt declarate în afara oricărei funcţii şi sunt vizibile (pot fi utilizate) în tot programul (în programul principal şi în subprograme) din momentul declarării lor.
Exemplul 5.1 |
Exemplul 5.2 |
Exemplul 5.3 |
int N; void f1() { int x=5; N=10; cout << endl< cout << endl << x; } int main () { N=4; cout << N; f1(); } |
int N; void f1() { int x=5; cout << endl << x; P=2; } int P=9; int main () {f1(); cout << x; P=7; } |
int N; void f1(int p) { int x=p; cout << x; } int main () { f1(77); } |
N este variabilă globală si poate fi accesată în cadrul oricărei funcţii. x este variabilă locală, vizibilă doar în cadrul funcţiei f1() Se va afişa: 4 10 5 |
Compilatorul generează eroare deoarece
|
Se afişează 77 N este variabilă globală. Poate fi accesată în cadrul oricărei funcţii. x este variabilă locală. Poate fi accesată doar în cadrul funcţiei f1() p este parametru formal. Poate fi accesat doar în f1(). |
5.4. Regula de omonimie
În cazul în care există o variabilă locală care are acelaşi 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<<" "; } int main () { f1(); cout << N; } |
Variabila N este definită atât ca variabilă globală cât şi ca variabilă locală în f1(). Se va afisa: 2 10 Funcţia f1() acţionează asupra variabilei locale N. Funcţia main() acţionează supra variabilei globale N. |
Întrebare. Cum gestionează compilatorul cele două variabile omonime ?
Răspuns:
Variabilelor globale li se rezervă spaţiu de memorie la începutul execuţiei programului, într-o zonă de memorie numită “zonă de date”. Acest spaţiu va fi ocupat până la încheierea execuţiei programului.
Variabilelor locale li se rezervă spaţiu într-o zonă specială de memorie numită “stiva”. La încheierea execuţiei subprogramului, conţinutul stivei este eliberat. Din acest motiv, variabilele locale sunt vizibile doar în interiorul subprogramului în care au fost declarate.
6. Parametrii formali şi parametrii actuali
Parametrii formali apar în antetul subprogramului şi sunt utilizaţi de subprogram pentru descrierea abstractă a unui proces de calcul .
Parametrii actuali apar în instrucţiunea de apelare a uni subprogram şi sunt folosiţi la execuţia 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 execuţiei instrucţiunii de apelare a subprogramului.
7. Apel prin valoare şi apel prin referinţă
Există două tipuri de apel al subprogramelor:
#include <iostream.h>
void test(int n) {
n++;
cout << n << endl; // tipăreşte n=8
}
void main() {
int n = 7;
test(n);
cout << n << endl; // tipăreşte n=7
}
Parametrul n este transmis prin valoare. În funcţia main() acest parametru este iniţializat cu valoarea 7. Când apelăm funcţia test(), se rezervă spaţiu pe stivă, spaţiu care are numele parametrului formal (în acest caz, tot n) şi care este iniţializat cu valoarea memorată de variabila n a programului principal. Altfel spus, pe stivă se copie valoarea parametrului efectiv de apel. În funcţie, variabila n (care este locală acestei funcţii) este incrementată şi devine 8, valoare care va fi tipărită. La ieşirea din funcţie, variabila n din stivă se pierde, adică nu mai are spaţiu alocat, prin urmare valoarea 8 este pierdută. În main() se tipăreşte valoarea variabilei n (locală acesteia) care are valoarea 7.
Se observă că, în momentul apelului funcţiei test(), pe stivă sunt alocate două variabile cu acelaşi nume n. Prima variabilă este variabila locală funcţiei main() care se salvează pe stivă în momentul apelului pentru a putea reface contextul funcţiei main() după încheierea apelului. A doua variabilă este parametrul formal tip valoare n, vizibil numai în funcţia test() şi iniţializat în momentul apelului cu valoarea 7. Indiferent ce valori primeşte acest n în corpul funcţiei test(), după încheierea execuţiei acestei funcţii, spaţiul său este de alocat din stivă, adică variabila respectivă este distrusă. Din acest motiv, după execuţia funcţiei test(), conţinutul stivei este cel din dreapta. Se reface contextul din care s-a lansat apelul funcţiei test(), adică se recuperează din stivă valoarea variabilei locale n=7 şi adresa de revenire, adică adresa instrucţiunii cout.
b) Expresii. În acest caz, parametrii efectivi sunt expresii, care pot conţine şi funcţii şi care mai întâi se evaluează. Exemplu:
#include <iostream.h>
#include <math.h>
void test(int n) {
cout << n << endl;
}
void main() {
test(5); // se va tipări 5
test(7 + (int)sqrt(45)); // se va tipări 13
}
În funcţie se creează o variabilă numităn, reţinută pe stivă, care la primul apel va primi valoarea 5 şi la al doilea apel valoarea 13.
La ieşirea din funcţie conţinutul acestei variabile se pierde.
Transmiterea parametrilor prin valoarese utilizează când nu dorim ca subprogramul apelat să poată modifica parametrii efectivi de apel. Acesta este modul implicit de transmitere a parametrilor în limbajul C. Dacă nu ar exista decât transmiterea prin valoare, ar fi imposibil să modificăm valoarea anumitor valori care sunt declarate în blocul apelator.
7.2. Apel prin referinţă - se transmite adresa parametrului actual.
În cazul apelului prin referinţă, subprogramul, cunoscând adresa parametrului actual, acţionează direct asupra locaţiei de memorie indicată de aceasta, modificând valoarea parametrului actual.
Parametrii transmisi prin referinta se folosesc pentru transmiterea de rezultate in afara functiei. Ei se pot modifica in corpul functiei dar dupa terminarea apelului functiei au valoarea pe care au primit-o in timpul apelului functiei.
În C++, implicit, apelul se face prin valoare. Pentru a specifica un apel prin referinţă, în lista parametrilor formali, numele parametrului formal va trebui precedat de 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; } int main () { int M=1, N=5; schimba_valoare(M,N); cout << "M="< schimba_referinta(M,N); cout << "M="< } |
APEL PRIN VALOARE APEL PRIN REFERINŢĂ Se va afişa: M=1 N=5 M=5 N=1 |
FISA DE LUCRU 1.doc
FISE DE LUCRU 3_FISEdincapitolulsubprograme2009_2010.doc
TESTETEST_SUBPROGRAME.doc
APLICATII http://info.mcip.ro/?cap=Subprograme