2010-08-07 12 views
9

Mi chiedo quale sarebbe il modo migliore per memorizzare le costanti matematiche utilizzate in un intero programma?C: enum VS #define per le costanti matematiche?

#define PI 3.14159265 
#define SPEEDOFLIGHT 2.99792458e8 

o

enum constants { PI = 3.14159265; SPEEDOFLIGHT = 2.99792458e8; } 

Grazie

risposta

12

Non utilizzare const variabili per Questo! Nel linguaggio C, una variabile qualificata const è non una costante nel senso dell'espressione costante, quindi non può essere utilizzata nell'inizializzazione di una variabile statica/globale. Ciò ha importanti conseguenze pratiche; per esempio, il seguente non funziona:

static const double powers_of_pi[] = { 1, PI, PI*PI, PI*PI*PI, PI*PI*PI*PI, }; 

La soluzione corretta è #define. Probabilmente è meglio usare il suffisso l in modo che abbiano il tipo long double e includere un numero sufficiente di posizioni decimali che i valori siano corretti per i tipi long double fino a 128 bit. Quindi puoi usarli ovunque sia previsto un tipo a virgola mobile; C li convertirà silenziosamente in una precisione inferiore se necessario.

+3

+1: C const sono spazzatura. Ad esempio non puoi nemmeno farlo: 'static const double pi = 3.1415926; statico const double tau = 2 * pi; 'perché negli inizializzatori C const devono sempre essere presenti costanti di tempo, che pi non è. –

+1

Grazie per il supporto che ha iniettato un po 'di sanità mentale in questo argomento. Sembra che tutti gli altri provengano da uno sfondo C++ e pensa che ciò che funziona in C++ dovrebbe funzionare in C ... :-( –

+0

@Luther, non dovrebbero chiamarli spazzatura. Hanno un uso limitato, ma non certo quello di qualcuno quello che viene da uno sfondo in C++ si aspetta. 'const' non dovrebbe mai essere stato scelto come parola chiave per ciò che sta,' immutabile' o qualcosa del genere sarebbe stato molto più sano, per entrambi, C e C++. –

10

Nessuno di loro, usa valori costanti per preservare la verifica del tipo di compilatore:

static const double PI = 3.14159265; 
static const double SPEEDOFLIGHT = 2.99792458e8; 
  • L'#define è sola sostituzione testo e tipo inconsapevoli.
  • Le enumerazioni non sono adatte per tutti i tipi. Non sono sicuro, ma non credo nemmeno per i valori double.

MODIFICA: grazie aaa. Ho dimenticato la parola chiave static, particolarmente utile quando le costanti sono dichiarate nelle intestazioni c. (In C++ non è necessaria la statica)

+1

probabilmente dovrebbe renderli statici per evitare errori di linker – Anycorn

+0

stat const double è quindi, grazie ragazzi! –

+5

Questo è un pessimo consiglio. Ad esempio, non sarai in grado di usare espressioni che coinvolgono 'PI' come inizializzatori per i dati statici. –

3

Poiché le enum sono costanti numero intero, vorrei andare con #define.

Sono d'accordo con jdehaan che gli oggetti globali const sono ancora meglio.

+2

Complimenti per essere l'unica risposta a menzionare esplicitamente che enum' è solo per i tipi interi, ma non sono d'accordo che gli oggetti 'const' globali siano migliori (almeno non senza menzionare i loro limiti). – jamesdlin

1

D'accordo con jdehaan, preferisco che le costanti facciano un controllo/conversione di tipo più esplicito.

Inoltre, l'uso di un enumerisco come quello che hai descritto non è proprio lo scopo di un enum. Quelle costanti sono solo matematicamente correlate (se il cosmologo hocus-pocus finisce per essere corretto). Lo scopo di un enum è quella di combinare come valori, come ad esempio:

enum color 
{ 
    red = 0xFF0000; 
    yellow = 0xFFFF00; 
    baby_puke_green = 0x9ACD32; 
} 
5

Personalmente preferisco fare solo Pi e c = 1 e lasciare che l'affare universo con il problema

+2

O normalizza :) –