Il metodo con const alloca effettivamente spazio per memorizzare la costante, proprio come per le variabili.
Il metodo con #define è fondamentalmente un "trova e sostituisci". Nel senso che prima di compilare, il nome della costante viene sostituito con il valore effettivo.
quindi se scrivi
#define c 5
int main()
{
return c*2;
}
Viene compilato questo
int main()
{
return 5*2;
}