Ce face Programe din mai multe fișiere (.c și .h)
Un program mai mare se împarte în module. Fiecare modul are un antet (note.h) cu ce oferă celorlalte: prototipuri de funcții, tipuri (struct, typedef), constante și declarații extern. Implementarea stă în fișierul sursă cu același nume (note.c). Celelalte fișiere includ doar antetul, cu #include "note.h".
Fiecare fișier .c este compilat separat într-un fișier obiect (clang -c note.c → note.o). Apoi legătorul (linker-ul) combină obiectele într-un executabil și leagă fiecare apel de definiția funcției. Dacă o funcție este declarată, dar definiția ei lipsește din fișierele legate, eroarea apare la legare: „Undefined symbols” (macOS) sau „undefined reference” (Linux).
Funcțiile și variabilele care sunt folosite doar într-un fișier se declară static, ca să nu fie vizibile în altele. O variabilă globală comună se definește într-un singur .c și se declară cu extern în antet.
Exemple
Exemplul 1: Antet, implementare și program principal
main.c cunoaște funcția media din antet. Cele două fișiere sursă se dau împreună compilatorului, care le compilează și le leagă într-o singură comandă.
// note.h
#ifndef NOTE_H
#define NOTE_H
double media(const int note[], int n);
#endif
// note.c
#include "note.h"
double media(const int note[], int n) {
int suma = 0;
for (int i = 0; i < n; i++) {
suma += note[i];
}
return (double)suma / n;
}
// main.c
#include <stdio.h>
#include "note.h"
int main(void) {
int note[] = {9, 10, 8, 7};
printf("Media Anei: %.2f\n", media(note, 4));
return 0;
}
// în terminal:
// clang -std=c23 -Wall -Wextra main.c note.c -o catalog
// ./catalog
Ieșire în terminal
Media Anei: 8.50
Exemplul 2: Compilare separată și legare
-c produce câte un fișier obiect, fără legare. Ultima comandă primește doar obiectele și face executabilul. Așa lucrează și make: după o modificare în note.c, recompilează doar note.o.
# în terminal, în directorul cu note.h, note.c și main.c:
clang -std=c23 -Wall -c note.c
clang -std=c23 -Wall -c main.c
clang main.o note.o -o catalog
ls -1
./catalog
Ieșire în terminal
catalog
main.c
main.o
note.c
note.h
note.o
Media Anei: 8.50
Exemplul 3: Eroare la legare: lipsește un fișier
Compilarea lui main.c reușește, pentru că antetul declară media. Dar note.c nu a fost dat compilatorului, deci legătorul nu găsește definiția (pe macOS numele apare cu _ în față).
# în terminal:
clang -std=c23 main.c -o catalog
Ieșire în terminal
Undefined symbols for architecture arm64:
"_media", referenced from:
_main in main-728b8e.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Greșeli frecvente
- Definești o variabilă globală în antet (
int total = 0;). Fiecare.ccare îl include creează propria variabilă, iar legarea dă „duplicate symbol”. În antet scrieextern int total;, iar definiția pune-o într-un singur.c. - Nu incluzi propriul antet în fișierul de implementare (
note.cfără#include "note.h"). Dacă prototipul și definiția diferă, compilatorul nu are cum să observe. - Uiți garda de includere și antetul ajunge inclus de două ori, cu redefinirea tipurilor din el. Vezi
#include.
Comenzi înrudite
#include: Copiază conținutul unui fișier antet (.h) în locul liniei, ca funcțiile și tipurile declarate acolo să poată fi folosite.make și Makefile: make citește un Makefile și recompilează doar fișierele modificate, ca să nu scrii de fiecare dată comenzile de compilare.Compilarea cu gcc și clang: Cum transformi codul C într-un program executabil cu gcc sau clang și ce fac opțiunile folosite cel mai des.extern: Declară o variabilă globală definită în alt fișier (sau mai jos), ca să o poți folosi fără să creezi o copie nouă.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.Funcții și prototipuri: Cum definești și declari funcții în C: tipul rezultatului, parametrii, prototipul și transmiterea argumentelor prin valoare.
Întrebări & Exemple de Cod:
Programe din mai multe fișiere (.c și .h)Ai o nelămurire despre utilizarea comenzii
Programe din mai multe fișiere (.c și .h)sau ai descoperit un truc / fragment de cod util? Distribuie-l cu ceilalți programatori!Fii primul care pune o întrebare sau distribuie un fragment de cod / prompt!
Nu au fost adăugate încă întrebări sau exemple de cod pentru această pagină. Dacă ai întâlnit o problemă sau ai un snippet util, adaugă-l mai jos pentru a-i ajuta pe ceilalți.