Ce face Funcții și prototipuri
O funcție are un tip de rezultat, un nume, o listă de parametri și un corp. return trimite rezultatul înapoi; o funcție void nu returnează nimic. Compilatorul trebuie să vadă declarația unei funcții înainte de primul apel: fie definiția completă, fie un prototip (doar antetul, terminat cu punct și virgulă), de obicei pus într-un fișier .h.
În C, argumentele se transmit prin valoare: funcția primește o copie. Dacă modifici parametrul în funcție, variabila din apel rămâne neschimbată. Ca să modifici variabila celui care apelează, trimiți adresa ei (un pointer).
Din C23, int f() înseamnă la fel ca int f(void): funcție fără parametri. În standardele mai vechi, parantezele goale însemnau „parametri nespecificați”. Tot din C23 (și deja din C99 cu avertisment), apelarea unei funcții nedeclarate este eroare.
Parametri
| Parametru | Descriere |
|---|---|
tip_returnat |
Tipul valorii returnate (int, double, char *…) sau void. |
parametri |
Lista de parametri, fiecare cu tipul lui; void sau nimic pentru „fără parametri”. |
Exemple
Exemplul 1: Prototip înainte de main, definiție după
Prototipul de sus permite apelul din main, chiar dacă definiția vine mai jos.
#include <stdio.h>
double pret_cu_tva(double pret, double cota); // prototip
int main(void) {
printf("Laptop: %.2f lei\n", pret_cu_tva(3000, 0.21));
printf("Carte: %.2f lei\n", pret_cu_tva(50, 0.11));
return 0;
}
double pret_cu_tva(double pret, double cota) {
return pret * (1 + cota);
}
Rezultat
Laptop: 3630.00 lei
Carte: 55.50 lei
Exemplul 2: Transmitere prin valoare
dubleaza modifică doar copia; x din main rămâne 5. Versiunea cu pointer modifică variabila originală.
#include <stdio.h>
void dubleaza(int n) {
n *= 2;
printf("în funcție: %d\n", n);
}
void dubleaza_prin_pointer(int *n) {
*n *= 2;
}
int main(void) {
int x = 5;
dubleaza(x);
printf("după dubleaza: %d\n", x);
dubleaza_prin_pointer(&x);
printf("după dubleaza_prin_pointer: %d\n", x);
return 0;
}
Rezultat
în funcție: 10
după dubleaza: 5
după dubleaza_prin_pointer: 10
Exemplul 3: Apel fără declarație: eroare în C23
Compilatorul nu știe ce este suma în momentul apelului. Soluția este un prototip deasupra lui main sau mutarea definiției mai sus.
#include <stdio.h>
int main(void) {
int total = suma(2, 3);
printf("%d\n", total);
return 0;
}
int suma(int a, int b) { return a + b; }
Eroare de compilare (clang)
exemplu.c:4:17: error: use of undeclared identifier 'suma'
4 | int total = suma(2, 3);
| ^~~~
1 error generated.
Greșeli frecvente
- Uiți
returnîntr-o funcție care nu estevoid. Dacă apelantul folosește rezultatul, comportamentul este nedefinit (-Wallavertizează). - Returnezi adresa unei variabile locale (
return &x;). Variabila dispare la ieșirea din funcție; foloseștestatic, memorie alocată sau un parametru de ieșire. - Aștepți ca funcția să modifice tabloul fără să îl primească, sau o variabilă simplă trimisă prin valoare. Pentru modificare trimite un pointer.
Comenzi înrudite
main: Funcția cu care începe orice program C: sistemul o apelează la pornire, iar valoarea returnată spune dacă programul a reușit.Recursivitate: O funcție care se apelează pe ea însăși, cu o problemă mai mică la fiecare pas, până la un caz de bază.Pointeri (& și *): O variabilă care păstrează adresa altei variabile; cu * citești sau modifici valoarea de la acea adresă.Pointeri la funcții: O variabilă care ține adresa unei funcții: o poți schimba, pune în tablouri sau trimite altor funcții (callback).Programe din mai multe fișiere (.c și .h): Cum împarți un program C în fișiere sursă (.c) și antete (.h), cum le compilezi separat și cum le legi într-un executabil.static: Într-o funcție, variabila își păstrează valoarea între apeluri; la nivel de fișier, ascunde funcția sau variabila de celelalte fișiere.