Programarea Calculatoarelor
Cursul 4: Funcții;Tablouri
Robert Varga
Universitatea Tehnică din Cluj-Napoca
Departamentul Calculatoare
Test 1 – săptămâna viitoare
• 1 noi, vineri, ora 10:10
• Durata: 40 min
• Pe foaie
• Fără documentație
• Două probleme• Reprezentarea datelor, tipuri, conversii
• Interpretare și corectare cod scurt
• Inclusiv funcții, fără tablouri
• Contează 1 punct din nota voastră la examen PC
• Dacă lipsiți primiți 0 -> nota maximă 9
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 2
Introducere
• Funcții• Permit modularizarea programelor
• Variabilele declarate în interiorul funcțiilor – variabile locale (vizibile doar în interior)
• Parametrii funcțiilor• Permit comunicarea informației între funcții
• Sunt variabile locale funcțiilor
• Avantajele utilizării funcțiilor• Divizarea problemei în subprobleme
• Managementul dezvoltării programelor
• Utilizarea/reutilizarea funcțiilor scrise în alte programe
• Abstractizare – ascunderea informației interne (funcții în biblioteci)
• Elimină duplicarea codului scris
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 3
Structura unei funcții
tip_returnat nume(lista_parametri_formali){
declaratiiinstructiuni
}
• nume - un identificator valid
• tip_returnat – tipul de dată al rezultatului (implicit este int)
• Primul rând se numește antetul funcției (header)
• Lista de parametri formali poate conține• Nici un parametru:
tip_returnat nume()
tip_returnat nume(void)
• Unul sau mai mulți parametri separați prin virgulă. Un parametru formal este specificat prin tip identificator
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 4
Valoarea returnată
• Două categorii de funcții• Care returnează o valoare: prin utilizarea instrucțiunii
return expression;
• Care nu returnează nicio valoare: prin instrucțiunea
return;
În acest caz tip_returnat este înlocuit cu void
• Returnarea valorii
• Declarațiile și instrucțiunile din funcții sunt executate până se întâlnește
• Instrucțiunea return
sau
• Până execuția atinge finalul funcției – acolada închisă }
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 5
Valoarea returnată
int adunare(int a, int b)
{
printf("Functie care calculeaza si returneaza suma a
doi intregi\n");
int suma;
suma = a+b;
return suma;
printf("Aceasta instructiune nu se mai executa\n");
}
int max_int()
{
printf("Functie care returneaza cel mai mare intreg
pozitiv\n");
return 0x7FFFFFFF;
}
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 6
Valoarea returnată
void impar(int x)
{
printf("Functie care afiseaza daca un numar este par
sau impar\n");
if (x%2==1)
printf("%d este numar impar\n",x);
else
printf("%d este par\n",x);
return;
printf("Aceasta instructiune nu se mai executa\n");
}
void patrat(int a)
{
printf("Functie care afiseaza patratul unui numar\n");
printf("%d^2=%d\n",a,a*a);
}
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 7
Prototipul și argumentele funcțiilor
• Prototipul unei funcții constă în specificarea antetului urmat de caracterul ;
• Nu este necesară specificarea numelor parametrilor formaliint adunare(int, int);
• Este necesară inserarea prototipului unei funcții înaintea altor funcții în care este invocată dacă implementarea ei este localizată după implementarea acelor funcții
• Parametrii apar în definiții
• Argumentele apar în apelurile de funcții• În limbajul C - trimiterea argumentelor se face prin valoare
• Regula de conversie a argumentelor• În cazul în care diferă, tipul fiecărui argument este convertit automat la
tipul parametrului formal corespunzător • Ca și în cazul unei simple atribuiri
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 8
Prototipul și argumentele funcțiilor
double f(double t){
return t-1.5;}
float g(int);
int main()
{
float a=11.5f;printf("%f\n",f(a));
printf("%f\n",g(a));
}
float g(int z)
{
return z+2.f;}
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 9
Rezultat afișat
10.000000
13.000000
Prototipul și argumentele funcțiilor
#include <stdio.h>
#include <math.h>
int main()
{
float f;
scanf("%f", &f);
printf("trunc %d\n", (int)f);
printf("floor %d\n", (int)round(f));
printf("round %d\n", (int)floor(f));
printf("ceil %d\n", (int)ceil(f));
return 0;
}
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 10
Apelul funcțiilor
• Funcție care nu returnează nici o valoare
nume(lista_parametri_actuali);
• Funcție care returnează o valoare• Ca și mai sus, valoarea returnată fiind pierdută
• Ca și un operand într-o expresie, valoarea returnată fiind utilizată în evaluarea expresiei
• Exemplu de memorare a valorii returnate într-o variabilă: variabila=nume(lista_parametri_actuali);
• Corespondența între parametrii formali și actuali este pozițională
• În cazul în care tipul unui parametru actual este diferit de tipul parametrului formal corespunzător, acesta este convertit automat la tipul parametrului formal
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 14
Apelul funcțiilor
• Utilizat la invocarea funcțiilor
• În limbajul C apelul se poate face doar prin valoare• O copie a argumentelor este trimisă funcției
• Modificările în interiorul funcției nu afectează argumentele originale
• În limbajul C++ apelul se poate face și prin referință• Argumentele originale sunt trimise funcției
• Modificările în interiorul funcției afectează argumentele trimise
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 15
Apel prin valoare
Valorile argumentelor a și b nu sunt interschimbate după apelul funcției
#include <stdio.h>
#include <stdlib.h>
/* interschimbarea valorilor a si b */
void interschimba(int a, int b)
{
int aux;
printf("\nLa intrarea in functie: a=%d b=%d\n", a, b);
aux = a; a = b; b = aux;
printf("\La iesirea din functie: a=%d b=%d\n", a, b);
}
int main()
{
int a=3, b=2;
printf("\nIn main inainte de apelul functiei: a=%d b=%d\n", a, b)
interschimba(a, b);
printf("\nIn main dupa apelul functiei: a=%d b=%d\n", a, b)
return 0;
}
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 16
Calitatea unei funcții
• Este apelată de foarte multe ori
• Face codul care o apelează mult mai compact și mai ușor de citit
• Rezolvă o anumită problemă bine specificată și o rezolvă foarte bine
• Interfața cu restul programului este clară și scurtă
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 18
Apelul funcției și procesul de revenire din apel
• Etapele principale ale apelului unei funcției și a revenirii din acesta în funcția de unde a fost apelată
• Argumentele apelului sunt evaluate și trimise funcției
• Adresa de revenire este salvată pe stivă
• Controlul trece la funcția care este apelată
• Funcția apelată alocă pe stivă spațiu pentru variabilele locale și
pentru cele temporare
• Se execută instrucțiunile din corpul funcției
• Dacă există valoare returnată, aceasta este pusă într-un loc sigur
• Spațiul alocat pe stivă este eliberat
• Utilizând adresa de revenire controlul este transferat în funcția care
a inițiat apelul, după acesta
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 19
Stiva în C
• La execuția programelor C se utilizează o structură internă numită stivă (stack) și care este utilizată pentru alocareamemoriei și manipularea variabilelor temporare
• Pe stivă sunt alocate și memorate:• Variabilele locale din cadrul funcțiilor• Parametrii funcțiilor• Adresa de revenire din apelul funcțiilor
• Dimensiunea implicită a stivei este redusă• În timpul execuției programele trebuie să nu depășească
dimensiunea stivei• Dimensiunea stivei poate fi modificată în prealabil din setările
editorului de legături (linker)
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 20
Stiva în C – depășirea dimensiunii
int f()
{
int a[10000000]={0};
}
int main()
{
f();
return 0;
}
int f(int a,int b)
{
if (a<b)
return 1+f(a+1,b-1);
else
return 0;
}
int main()
{
printf("%d",f(0,1000000));
}
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 21
Ambele programe eșuează în timpul execuției din cauza
depășirii dimensiunii stivei
Declararea variabilelor tablou
tip_baza identificator[lim] [lim] , identificator[lim] [lim] ;
• Indicii sunt de la 0 la lim-1 inclusiv
• Limitele sunt expresii constante, evaluate în timpul compilării
• În C99 limitele pot fi şi variabile
• Numele unui tablou reprezintă adresa primului său element
• Exemple de declarări de tablouri:int vector[100]; //tablou unidimensional
double matrice[10][15]; //tablou bidimensional
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 22
Iniţializarea variabilelor tablou
• Tablou bidimensional declarat și inițializattip_baza identificator[lim1][lim2] = {
{v00, v01,..., v0n},
{v10, v11 ,..., v1m},
...
{vi0, vi1 ,..., vik}
};• Exemplu
int mat[5][5] =
{
{1, 2, 3},
{5, 6, 7, 8},
{9, 10, 11},
};• Restul elementelor se initializează la 0
• mat[0][3] si mat[4][4] sunt 0
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 23
Iniţializarea variabilelor tablou –poziţii specifice - C99
• Putem specifica valorile ale doar câtorva elemente specifice• In loc de
int a[15] = {0, 0, 29, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 48}
• Putem folosi
int a[15] = {[2] = 29, [9] = 7, [14] = 48}
• Sau
int a[15] = {[14] = 48, [2] = 29, [9] = 7}
• Se poate mixa cu iniţializarea clasică
int c[] = {0, 1, 2, [4] = 4, [3] = 3}
• Se deduce dimensiunea lui c în mod automat ca fiind 5
• Pentru tablouri bidimensionale
int I[][] = {[0][0] = 1, [1][1] = 1}
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 24
Transmiterea variabilelor tablou ca şi argumente la funcţii
• Tablou unidimensional• În prototipul funcţiei se specifică prin
tip nume[] sau tip nume[dimensiune]
• La apel se trimite numele tabloului
• Dacă dimensiunea nu este constantă trebuie trimisă separat
• Tablou multidimensional• În prototipul funcţiei se specifică prin:
tip nume[][dim_2]...[dim_n]
• Trebuie să furnizăm toate dimensiunile în afară de prima (opţional)
• La apel se trimite numele tabloului
• Dacă dimensiunile nu sunt constante trebuie trimise separat
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 25
Exemplu variabile tablou
//Exemplu de citire, manipulare si afisare tablou
#include <stdio.h>
int main()
{
int a[5];
for(int i=0; i<5; i++){
printf("a[%d] = ", i);
scanf("%d", &a[i]);
}
for(int i=0; i<5; i++)
a[i] = 2*a[i];
for(int i=0; i<5; i++)
printf("a[%d] = %d\n", i, a[i]);
return 0;
}
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 26
Exemplu variabile tablou
//Cititi elementele unei matrice nxn
//salvati cele de pe diagonala intr-un tablou
#include <stdio.h>
void citire(int n, float a[][n]){
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
printf("a[%d][%d] = ", i, j);
scanf("%f", &a[i][j]);
}
}
}
void diag(int n, float a[][n], float d[]){
for(int i=0; i<n; i++)
d[i] = a[i][i];
}
int main(){
int n=2;
float a[n][n];
float d[n];
citire(n, a);
diag(n, a, d);
for(int i=0; i<n; i++)
printf("%f ", d[i]);
return 0;
}
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 27
Tablouri – de ştiut
• Limbajul C nu verifică limitele tabloului la accesare• Puteţi accesa zone de memorie care nu fac parte din tablou
• De ex. int a[5]; a[5] = 5; <- greşit
• Primul element este la poziţia 0, ultimul la n-1• Unde n este numărul total de elemente
• De ex. int a[5]; a[0] = 5; a[4] = 1;
• Operatorul sizeof poate fi folosit pentru determinarea numărului de elemente din tabloul alocat
int nr_elemente = sizeof(a)/sizeof(a[0])
• Nu funcţionează dacă apelăm pe numele tabloului trimis la o funcţie
• Tablourile cu dimensiune variabilă nu se pot iniţializa
• Valorile dintr-un tablou trimis la o funcţie se pot modifica în interiorul funcţiei
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 28
Interschimbare - revizitat
#include <stdio.h>
#include <stdlib.h>
/* interschimbarea valorilor a si b */
void interschimba(int ab[])
{
int aux;
printf("\nLa intrarea in functie: a=%d b=%d\n", ab[0], ab[1]);
aux = ab[0]; ab[0] = ab[1]; ab[1] = aux;
printf("\La iesirea din functie: a=%d b=%d\n", ab[0], ab[1]);
}
int main()
{
int a=3, b=2;
int ab[] = {a, b};
printf("\nIn main inainte de apelul functiei: a=%d b=%d\n", ab[0], ab[1]);
interschimba(ab);
printf("\nIn main dupa apelul functiei: a=%d b=%d\n", ab[0], ab[1]);
return 0;
}
18 octombrie 2019 Programarea Calculatoarelor - R. Varga 29
Top Related