Ce face typedef
typedef nu creează un tip nou, ci un alias pentru unul existent. După typedef unsigned long long Lei; poți scrie Lei total;, care este exact un unsigned long long.
Cel mai des se folosește la structuri, ca să nu mai scrii struct la fiecare declarație: typedef struct { ... } Punct;. Dacă structura trebuie să se refere la ea însăși (o listă înlănțuită), îi dai și un nume de struct, pentru că aliasul nu există încă în interiorul definiției.
typedef face mult mai lizibile tipurile de pointeri la funcții. Biblioteca standard îl folosește pentru size_t, FILE, int32_t și multe altele.
Exemple
Exemplul 1: Alias pentru o structură
Cu typedef, tipul se scrie Punct, fără struct în față.
#include <stdio.h>
#include <math.h>
typedef struct {
double x, y;
} Punct;
double distanta(Punct a, Punct b) {
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
int main(void) {
Punct a = {0, 0}, b = {3, 4};
printf("distanța = %.1f\n", distanta(a, b));
return 0;
}
Rezultat
distanța = 5.0
Exemplul 2: Structură care se referă la ea însăși
În interiorul definiției se folosește struct nod, pentru că aliasul Nod apare abia la final.
#include <stdio.h>
typedef struct nod {
const char *oras;
struct nod *urmator;
} Nod;
int main(void) {
Nod c = {"Brașov", NULL};
Nod b = {"Cluj-Napoca", &c};
Nod a = {"Iași", &b};
for (const Nod *p = &a; p != NULL; p = p->urmator) {
printf("%s\n", p->oras);
}
return 0;
}
Rezultat
Iași
Cluj-Napoca
Brașov
Exemplul 3: Alias pentru un pointer la funcție
Operatie este tipul „pointer la o funcție care primește doi int și returnează int”. Tabloul de operații se citește mult mai ușor așa.
#include <stdio.h>
typedef int (*Operatie)(int, int);
int aduna(int a, int b) { return a + b; }
int inmulteste(int a, int b) { return a * b; }
int main(void) {
Operatie ops[] = {aduna, inmulteste};
const char *nume[] = {"suma", "produs"};
for (int i = 0; i < 2; i++) {
printf("%s: %d\n", nume[i], ops[i](6, 7));
}
return 0;
}
Rezultat
suma: 13
produs: 42
Greșeli frecvente
- Crezi că
typedefcreează un tip distinct.typedef int Lei; typedef int Euro;sunt amândouăint, iar compilatorul nu te oprește să le amesteci. - Ascunzi un pointer într-un
typedef(typedef struct nod *NodPtr;). Codul devine greu de citit: nu se mai vede că lucrezi cu pointeri, iarconst NodPtrînseamnă pointer constant, nu date constante. - Folosești aliasul în interiorul propriei definiții (
Nod *urmator;înainte să existeNod). Foloseștestruct nod *acolo.
Comenzi înrudite
struct: Grupează mai multe valori de tipuri diferite într-un singur tip nou, de exemplu numele, vârsta și orașul unei persoane.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).enum: Definește un set de constante întregi cu nume, de exemplu zilele săptămânii sau stările unei comenzi.stdint.h și limits.h: Tipuri întregi cu dimensiune exactă (int32_t, uint8_t) și constantele cu valorile minime și maxime ale tipurilor (INT_MAX).union: Ca un struct, dar toate câmpurile folosesc aceeași zonă de memorie, așa că la un moment dat păstrează o singură valoare.