Sunteți pe pagina 1din 40

Scopul cursului

Funcții
 Introducere

 Definirea funcțiilor

 Prototipul funcțiilor

 Apelul funcțiilor

 Transmiterea parametrilor

 Fișiere header

Programarea calculatoarelor I - Gyorodi


Cornelia 1
Definirea funcţiilor
 Forma generală de definre a funcţiilor în limbajul C este următoarea :
return_ type function _name ( parameter_list )
{
secventa instructiunilor
}
unde:
return_ type - specifică tipul valorii returnate de funcţie
function_ name - numele funcţiei
parameter_list - lista parametrilor formali

 O funcţie poate returna orice tip de dată, cu excepţia tipului tablou.

Programarea calculatoarelor I - Gyorodi


Cornelia 2
Definirea funcţiilor
return_type func_name parameter-type list

int is_factor(int a, int b)


Declarații
{
int result;
if ( (a == 0) || (b == 0) )
result = 0; Instrucțiuni
else {
if (a % b == 0)
result = 1;
else
result = 0; Returnează o valoare
}
return result;
Trebuie utilizată numai
} o singură dată !!!

Programarea calculatoarelor I - Gyorodi


Cornelia 3
Definirea funcţiilor
 Dacă type nu este specificat, compilatorul C presupune că funcţia
returnează o valoare întreagă.

 Dacă o funcţie returnează o valoare care nu este întreagă


aceasta trebuie declarată în mod explicit.

 Există două moduri în care putem informa compilatorul asupra


tipului unei funcţii: metoda tradiţională şi metoda
prototipului.

Programarea calculatoarelor I - Gyorodi


Cornelia 4
Definirea funcţiilor - metoda tradiţională

 Metoda tradiţională presupune specificarea la începutul


programului a tipului de dată returnat de funcție și numele
acesteia, fără a preciza lista parametrilor formali
De exemplu, declaraţia :

double volume ();

informează compilatorul că funcţia volume ( ) va returna o


valoare double.
Programarea calculatoarelor I - Gyorodi
Cornelia 5
Definirea funcţiilor - metoda prototipului
 Metoda prototipului presupune specificarea la începutul programului a tipului de dată
returnat de funcție, numele acesteia precum și declararea numărului şi tipului
argumentelor funcţiei, adică folosirea prototipului funcţiei.

 Prototipul prin declararea numărului şi tipului argumentelor funcţiei permite limbajului C


să găsească orice nepotrivire între tipul argumentelor folosite pentru apelarea unei
funcţii şi tipul parametrilor declaraţi ai acesteia.

 Prototipul permite de asemenea compilatorului să verifice dacă numărul argumentelor cu


care a fost apelată o funcţie este acelaşi cu numărul parametrilor declaraţi ai funcţiei.

 Forma generală pentru definirea prototipului unei funcţii este următoarea :


type nume_functie ( type param1, type param2,..., type paramN );

Programarea calculatoarelor I - Gyorodi


Cornelia 6
Apelarea unei funcții
 O funcție se aplelează folosind sintaxa generală:

nume_functie(lista_parametri_actuali);

 O funcție poate apare ca operand într-o expresie, dacă funcția returnează o


valoare.
 Revenirea dintr-o funcție se face la întalnirea instrucțiunii return, sau la
terminarea execuției corpului funcției (în cazul funcțiilor void - care nu
returnează nici un rezultat).
 Corpul unei funcții poate conține una sau mai multe instrucțiuni return.

Programarea calculatoarelor I - Gyorodi


Cornelia 7
Exemplu de funcţii – definite prin metoda tradițională
 Programul următor foloseşte funcţia volume ( ).
# include < stdio h >

double volume ( ) ; /*declarăm funcţia volume( ) prin metoda tradiţională */


void main ( )
{
double vol ;
vol = volume ( 12.2, 5.5, 9.04 ) ;
printf ( " volumul este : %f " , vol ) ;
}

double volume ( double s1, double s2, double s3 )


{
return s1*s2*s3 ;
}

Programarea calculatoarelor I - Gyorodi


Cornelia 8
Funcţii
 Dacă funcţia nu returnează valori, funcţia poate fi declarată
ca fiind de tipul void. Aceasta instruieşte compilatorul că
funcţia nu returnează valori şi previne folosirea ei în partea
dreaptă a unei operaţii de asignare.

 Dacă o funcţie returnează un caracter, este permis ca tipul


funcţiei să fie considerat implicit int. Motivul constă în faptul
că limbajul C converteşte caracterele în întregi.

Programarea calculatoarelor I - Gyorodi


Cornelia 9
Prototipul funcțiilor
 A doua metodă de a informa compilatorul despre valoarea pe care o returnează
o funcţie este folosirea prototipului funcţiei.

 A fost adăugat de standardul ANSI.

 Forma generală pentru definirea prototipului unei funcţii este următoarea:

type function_name ( type param1, type param2,..., type


paramN )

Programarea calculatoarelor I - Gyorodi


Cornelia 10
Prototipul funcţiilor (cont.)
# include < stdio.h >
double volum( double s1, double s2, double s3 )
/* prototipul functiei volum * /

void main( ){
vol = volum ( 12.2, 5.67, 9.04 ) ;
printf ( " Volumul este % f ", vol ) ;
}
double volum( double s1, double s2, double s3 )
{
return s1*s2*s3 ;
}
Programarea calculatoarelor I - Gyorodi
Cornelia 11
Prototipul funcțiilor

 Avantaje:
 Permite limbajului C să găsească orice nepotrivire între tipul
argumentelor folosite pentru apelarea unei funcții și tipul
parametrilor declarați ai acesteia
 Verifică dacă numărul argumentelor cu care a fost apelată
funcția este același cu numărul parametrilor declarați ai funcției.
 În standardul ANSI o funcție care nu are parametri va conține
cuvântul void inchis între paranteze.

Programarea calculatoarelor I - Gyorodi


Cornelia 12
Apelul funcțiilor
 Apelăm o funcție astfel:
nume_functie( lista_parametri_actuali);

 Parametri din lista_parametri_actuali sunt separați prin virgulă


 Parametri actuali pot fi orice expresie validă.

if ( is_factor(num1 * 2, num2) == 0) {
...}

Programarea calculatoarelor I - Gyorodi


Cornelia 13
Apelarea unei funcții

 La apelul unei funcții, se execută corpul său, după care se revine


în funcția apelantă, la instrucțiunea următoare apelului.
 O funcție poate fi apelată, numai dacă aceasta a fost declarată
adică în fața apelului există definiția sau cel puțin declarația
funcției.
 Parametrii actuali sunt expresii, care trebuie să corespundă ca
număr și tip (eventual prin conversie implicită) cu parametrii
formali.

Programarea calculatoarelor I - Gyorodi


Cornelia 14
Apelarea unei funcții

 Parametrii actuali sunt transmiși prin valoare, la apelul funcției


(valorile lor sunt depuse pe stivă) iar modificarea valorii lor de
către funcție nu este vizibilă în exterior.

 La apelul unei funcții, pe stivă se crează o înregistrare de


activare, care cuprinde:
 adresa de revenire din funcție
 valorile parametrilor formali
 variabilele locale.

Programarea calculatoarelor I - Gyorodi


Cornelia 15
Aplelul funcțiilor

main
{ is_factor a b
3 6
… {
j = is_factor(3, 6); …
… return result;

}
calling function } called function

Programarea calculatoarelor I - Gyorodi


Cornelia 16
Apelul unei funcții

 Când o funcție este apelată, ea poate returna o valoare,


iar valoarea poate fi folosită într-o expresie sau poate fi
ignorată

 Este important să avem în vedere că parametrii actuali


sunt copiați în parametrii formali la apelarea unei funcții.

Programarea calculatoarelor I - Gyorodi


Cornelia 17
Apelul unei funcții

 În interiorul unei funcții parametrii formali sunt tratați ca


și variabile locale obșnuite și pot fi utilizați în aceeași
manieră ca și o variabilă locală.
 Parametrii formali sunt inițializați cu valorile parametrilor
actuali la apelul unei funcții
 O funcție trebuie declarată înainte ca ea să fie apelată,
dacă nu este deja definită.

Programarea calculatoarelor I - Gyorodi


Cornelia 18
Exemplu
 Exemplu 9.2. Programul citește valorile a 2 rezistențe și calculează
echivalentul în serie și în paralel a valorii acestora. Se vor defini două
funcții prin metoda prototipului pentru calcularea valorii în serie
respectiv în paralel.
#include <stdio.h>
#include <stdlib.h>

/* Prototipul functiilor */
float calcul_serie(float r1, float r2);
float calcul_paralel(float r1, float r2);

Programarea calculatoarelor I - Gyorodi


Cornelia 19
int main(void) {
float res1, res2;

printf("Introduceti valorile a 2 rezistente: ");


scanf("%f %f", &res1, &res2);

printf("R1 = %.2f\nR2 = %.2f\n", res1, res2);


printf("Echivalent serie a rezistentei = %f\n", calcul_serie(res1,
res2));
printf("Echivalent paralel a rezistentei = %f\n", calcul_paralel(res1,
res2));
return EXIT_SUCCESS;
}
float calcul_serie(float r1, float r2)
{
return r1 + r2;
}
float calcul_paralel(float r1, float r2)
{
return r1 * r2 / (r1 + r2);
}
Mai multe detalii în Bibl 1 - Exemplu 9.2 20
Exemplu
 Să se scrie un program care citeșe de la tastatură două numere întregi și verifică dacă
primul număr este multiplu celui de-al doilea. Se va defini o funcție cu parametri pentru a
verifica dacă primul număr este multiplul celuilalt.

#include <stdio.h>
#include <stdlib.h>

/* Declararea functie prin metoda prototipului */

int este_factor(int a, int b);

Programarea calculatoarelor I - Gyorodi


Cornelia 21
Exemplu (continuare)
int main(void)
{
int num1, num2;

printf("Introduceti 2 intregi: ");


scanf("%d%d", &num1, &num2);

/* Verifica daca este multiplu*/


if (este_factor(num1, num2) == 1)
printf("%d este multiplu a lui %d\n", num1, num2);
else
printf("%d Nu este multiplu a lui %d\n", num1, num2);

return EXIT_SUCCESS;
}
22
Programarea calculatoarelor I - Gyorodi Cornelia
Exemplu (continuare)
int este_factor(int a, int b)
{
int result;
if ( (a == 0) || (b == 0) )
result = 0;
else {
if (a % b == 0)
result = 1;
else
result = 0;
}
return result;
}
Mai multe detalii în Bibl 1 - Exemplu 9.3
Programarea calculatoarelor I - Gyorodi
Cornelia 23
Domeniu de vizibilitate - Variabile locale și variabile globale

 În limbajul C există două tipuri de variabile :


 Variabile locale
 Variabile globale
 Variabilele locale sunt declarate în interiorul unei funcții
 Variabilele locale au ca și domeniu de vizibilitate doar
blocul în care sunt declarate.

Programarea calculatoarelor I - Gyorodi


Cornelia 24
Domeniu de vizibilitate – funcții

 O funcție în limbajul C are acces numai la:


 datele locale ale ei
 variabilele din lista parametrilor formali
 datele globale

 O funcție în C nu are acces la:


 Datele locale ale altor funcții
 variabilele din lista parametrilor formali ale altor funcții

Programarea calculatoarelor I - Gyorodi


Cornelia 25
Domeniu de vizibilitate - Variabile locale și variabile globale

 Varaible globale (external)


 Funcțiile pot utiliza/ modifica variabilele globale
 Ele există pe toată durata execuției programului ( ele sunt
alocate static pe durata execuției programului)
 Ele sunt vizibile din punctul unde au fost declarate până la
sfârșitul fișierului.

Programarea calculatoarelor I - Gyorodi


Cornelia 26
Transmiterea parametrilor

 Există două moduri în care se pot transmite argumente


funcţiilor:
 transmiterea prin valori.

 transmiterea prin referinţă.

Programarea calculatoarelor I - Gyorodi


Cornelia 27
Transmiterea parametrilor prin valoare - Exemplu
#include <stdio.h>
#include <stdlib.h>

int f1(int a, float b);

float x;

int main(void) {
int a, b = 2, c;

a = b + 3;
scanf(“%f”, &x);
c = f1(2, x);
return EXIT_SUCCESS;
}

int f1(int a, float b) {


int x, c = 1;
x = a + b + c;
printf(“Local x = %d\n”, x);
return x;
} Programarea calculatoarelor I - Gyorodi
Cornelia 28
Transmiterea parametrilor
 Transmiterea prin valoare – Transmiterea argumentelor prin valori
constă în copierea valori unui argument în parametrul formal al funcţiei.
Schimbările făcute asupra parametrului formal în corpul funcţiei nu au nici
un efect asupra variabilei folosite în apelul funcţiei (parametru actual).
Astfel modificarea parametrilor formali nu afectează parametrii actuali.

 În transmiterea parametrilor prin referinţă, adresa variabilei este


copiată în parametrul formal. In corpul funcţiei, această adresă este
folosită pentru a accesa chiar variabila. Deci, schimbările făcute asupra
parametrului vor afecta variabila folosită pentru apelarea funcţiei.

Programarea calculatoarelor I - Gyorodi


Cornelia 29
Exemplu de transmitere prin valoare a parametrilor
# include < stdio.h >
void schimba( int i, int j ) ;

void main ( void ) {


int num1, num2 ;
num1 = 100 ;
num2 = 800 ;
printf("Inainte de apelul functiei: num1 : %d num2 : %d\n ", num1, num2 ) ;
schimba( num1, num2 ) ;
printf("Dupa apelul functiei: num1 : %d num2: %d\n ", num1, num2 ); /* se
va afisa aceleasi valori*/
}
/ * metoda transmitere prin valoare * /
void schimba( int i, int j )
{
int temp ;
temp = i;
i = j ;
j = temp ;
}
Programarea calculatoarelor I - Gyorodi
Cornelia 30
Exemplu de transmitere prin referinţă a parametrilor
# include < stdio.h >
void schimba( int *i, int *j ) ;

void main ( void ) {


int num1, num2 ;
num1 = 100 ;
num2 = 800 ;
printf( " Inainte de apelul functiei: num1 : %d num2 : %d\n ", num1, num2 )
;
schimba( &num1, &num2 ) ;
printf( " Dupa apelul functiei: num1 : %d num2: %d\n ", num1, num2 );
}
/ * schimbarea valorilor între ele, folosind metoda transmiterea prin referinta *
/
void schimba( int * i, int * j )
{
int temp ;
temp = *i;
*i = *j ;
*j = temp ;
} Programarea calculatoarelor I - Gyorodi
Cornelia 31
Transmiterea parametrilor - tipul tablou
 Dacă se dorește ca o funcție să modifice valoarea unei variabile, trebuie să i
se transmită pointerul la variabila respectivă.

 Dacă un tablou este folosit ca argument al unei funcţii, funcţia primeşte


numai adresa tabloului, deci nu o copie a întregului tablou, ceea ce
înseamnă că la declararea parametrilor funcţiei tipul pointerilor trebuie să fie
compatibil cu tipul tablourilor pe care le punctează.

 În cazul în care un parametru formal al funcției este un tablou, funcția poate


modifica valorile elementelor tabloului, primind adresa lui.

Programarea calculatoarelor I - Gyorodi


Cornelia 32
Transmiterea parametrilor - tipul tablou

 Există trei metode pentru a declara un parametru care să


primească un pointer către un tablou:
a) Parametrul trebuie declarat ca un tablou de acelaşi tip şi
dimensiune cu cel folosit pentru apelarea funcţiei.
b) Parametrul trebuie declarat ca un tablou fără dimensiune.
c) Parametrul trebuie declarat ca un pointer către tablou,
aceasta fiind metoda cea mai utilizată.

Programarea calculatoarelor I - Gyorodi


Cornelia 33
Exemplu
 Programul demonstrează cele trei metode de declarare a unui
parametru ca pointer către un tablou.
#include <stdio.h>
void f1(int num[5]);
void f2(int num[]);
void f3(int *num );
void main(void)
{
int tab[5] = { 1, 2, 3, 4, 5};

f1(tab);
f2(tab);
f3(tab);
}
Programarea calculatoarelor I -
34
Gyorodi Cornelia
void f1(int num[5])
{
int i;
for (i = 0; i < 5; i++)
printf(" %d ", num[i]);
}
void f2(int num[])
{
int i;
printf("\n");
for( i = 0; i < 5; i++)
printf(" %d ", num[i]);
}
void f3(int *num)
{
int i;
printf("\n");
for( i = 0; i < 5; i++)
printf(" %d ", num[i]);
}
Mai multe detalii în Bibl 1 - Exemplu 9.5
35
Fișiere Header
 Fișierele header
 Conțin prototipul funcțiilor de biblotecă

 <stdlib.h> , <math.h> , etc

 Se încarcă folosind directiva:


#include <filename>
Exemplu:
#include <math.h>
 Crearea unui fișier header se realizează astfel:
 Creem un fișierul

 Salvăm fișierul folosind extensia .h (filename.h)

 Incărcăm fișierul în alt fișier folosind directiva


#include "filename.h"

Programarea calculatoarelor I - Gyorodi


Cornelia 36
Fișiere Header

 Scrierea numelui fișierului între ghilimele va determina


compilatorul să caute fișierul în directorul curent.

 Dacă specificăm numele fișierului închis în paranteze


unghiulare, instruim compilatorul să caute fișierul într-un
director destinat să conțină fișiere header.

Programarea calculatoarelor I - Gyorodi


Cornelia 37
Fișiere Header
 Dacă un fișier header se întâmplă să fie inclus de două ori,
compilatorul va procesa conținutul de două ori și va avea ca
rezultat o eroare.
 Modul standard de a preveni acest lucru este de a include
întregul conținut real al fișierului într-o instrucțiune
condițională, de forma:
#ifndef HEADER_FILE
#define HEADER_FILE
/*include fisierul*/
#endif

Programarea calculatoarelor I - Gyorodi


Cornelia 38
Fișiere Header
 Uneori este necesar să selectați unul dintre numeroasele fișiere header care
vor fi incluse în program.
 De exemplu, ați putea specifica parametrii de configurare care să fie
utilizați pe diferite tipuri de sisteme de operare. Puteți face acest lucru cu o
serie de instrucțiuni condiționale, după cum urmează:
#if SYSTEM_1
# include "system_1.h"
#elif SYSTEM_2
# include "system_2.h"
#elif SYSTEM_3
...
#endif

Programarea calculatoarelor I - Gyorodi


Cornelia 39
Mulțumesc pentru atenție!

Programarea calculatoarelor I - Gyorodi


Cornelia 40

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