#define în C

Definește o macro: un nume pe care preprocesorul îl înlocuiește cu textul dat, înainte ca programul să fie compilat.

Sintaxă
#define NUME valoare
#undef NUME

clang -DNUME=valoare program.c

Ce face #define

Înainte de compilarea propriu-zisă, fiecare fișier C trece prin preprocesor. Acesta execută liniile care încep cu #. #define TVA 0.21 îi spune preprocesorului: oriunde apare cuvântul TVA în cod, pune textul 0.21. Compilatorul nu vede niciodată numele TVA, ci doar valoarea.

Înlocuirea este pur textuală: preprocesorul nu știe tipuri și nu verifică nimic. De aceea o macro nu are tip, nu ocupă memorie și nu poate fi văzută în debugger. Prin convenție, numele de macro se scriu cu litere mari, ca să se vadă că nu sunt variabile. #undef NUME șterge definiția, iar opțiunea -DNUME=valoare a compilatorului definește o macro din linia de comandă, fără să modifici codul.

Compilatorul are și macro predefinite: __LINE__ (linia curentă), __FILE__ (numele fișierului), __STDC_VERSION__ (standardul folosit, de exemplu 202311L pentru C23), __DATE__ și __TIME__. Pentru constante cu tip, în C23 există și constexpr.

Parametri

Parametru Descriere
NUME Identificatorul macro-ului. Prin convenție, cu litere mari: TVA, MAX_ELEVI.
valoare Textul care înlocuiește numele, până la sfârșitul liniei. Poate lipsi: #define DEBUG definește doar numele (util pentru #ifdef).

Exemple

Exemplul 1: Constante pentru un calcul de preț

TVA și MAX_PRODUSE sunt înlocuite în cod înainte de compilare. MAX_PRODUSE poate fi folosit chiar ca dimensiune de tablou, pentru că după înlocuire acolo scrie 3.

#include <stdio.h>

#define TVA 0.21
#define MAX_PRODUSE 3

int main(void) {
    double preturi[MAX_PRODUSE] = {100.0, 45.5, 12.0};
    for (int i = 0; i < MAX_PRODUSE; i++) {
        printf("%.2f lei fără TVA -> %.2f lei cu TVA\n", preturi[i], preturi[i] * (1 + TVA));
    }
    return 0;
}

Rezultat

100.00 lei fără TVA -> 121.00 lei cu TVA
45.50 lei fără TVA -> 55.05 lei cu TVA
12.00 lei fără TVA -> 14.52 lei cu TVA

Exemplul 2: Macro predefinite și #undef

__STDC_VERSION__ are tipul long (de aceea %ld). După #undef ORAS, numele nu mai există, iar a doua definiție îl poate înlocui fără avertisment.

#include <stdio.h>

#define ORAS "Iași"

int main(void) {
    printf("Standard C: %ld\n", __STDC_VERSION__);
    printf("Linia curentă: %d\n", __LINE__);
    printf("Oraș: %s\n", ORAS);
#undef ORAS
#define ORAS "Cluj-Napoca"
    printf("Oraș nou: %s\n", ORAS);
    return 0;
}

Rezultat

Standard C: 202311
Linia curentă: 7
Oraș: Iași
Oraș nou: Cluj-Napoca

Exemplul 3: Ce vede compilatorul după preprocesare

Opțiunea -E oprește compilarea după preprocesor și afișează codul rezultat (-P ascunde marcajele de linie). Se vede că numele macro au dispărut, înlocuite cu textul lor.

// pret.c
#define TVA 0.21
#define PRET_CU_TVA(p) ((p) * (1 + TVA))

double total = PRET_CU_TVA(100.0);

// în terminal:
// clang -E -P pret.c

Ieșire în terminal

double total = ((100.0) * (1 + 0.21));

Greșeli frecvente

  • Pui punct și virgulă la final: #define TVA 0.21;. Punctul și virgula devine parte din text, iar pret * TVA + 1 se transformă în pret * 0.21; + 1, cu erori greu de înțeles.
  • Scrii o expresie fără paranteze: #define TOTAL 10 + 5, apoi TOTAL * 2 dă 10 + 5 * 2 = 20, nu 30. Pune mereu expresia între paranteze: #define TOTAL (10 + 5).
  • Folosești #define pentru constante unde ar merge const, enum sau constexpr. Acestea au tip, sunt verificate de compilator și apar în debugger.

Comenzi înrudite

  • Macro cu parametri: Macro care primesc argumente, ca o funcție: textul lor este copiat în locul apelului, cu operatorii # și ## și argumente variabile.
  • #if, #ifdef, #ifndef: Compilare condiționată: preprocesorul păstrează sau elimină bucăți de cod în funcție de macro definite sau de valoarea lor.
  • #include: Copiază conținutul unui fișier antet (.h) în locul liniei, ca funcțiile și tipurile declarate acolo să poată fi folosite.
  • constexpr: Declară o constantă cu valoare calculată la compilare, cu tip, care poate fi folosită ca dimensiune de tablou sau în static_assert.
  • const: Marchează o variabilă ca doar pentru citire: compilatorul oprește orice încercare de a o modifica.
  • 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.
Comunitate & Schimb de cunoștințe

Întrebări & Exemple de Cod: #define

Ai o nelămurire despre utilizarea comenzii #define 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.

Comunitate Adaugă o întrebare sau distribuie un cod

Moderare & Siguranță:

Pentru a menține calitatea și securitatea informațiilor, fiecare întrebare sau fragment de cod/prompt este analizat (manual sau prin moderare asistată de AI) înainte de publicare.