varias superponer studio lineas histogramas graficos graficas c coding-style c-preprocessor

studio - superponer graficas en r



¿Por qué la mayoría de los desarrolladores de C usan define en lugar de const? (9)

Esta pregunta ya tiene una respuesta aquí:

En muchos programas, un #define cumple el mismo propósito que una constante. Por ejemplo.

#define FIELD_WIDTH 10 const int fieldWidth = 10;

Normalmente veo la primera forma preferida sobre la otra, confiando en el preprocesador para manejar lo que básicamente es una decisión de la aplicación. ¿Hay alguna razón para esta tradición?


Algunos compiladores C almacenarán todas las variables const en el binario, que si se prepara una gran lista de coeficientes puede consumir una gran cantidad de espacio en el mundo integrado.

Por el contrario: el uso de const permite el flasheo sobre un programa existente para alterar parámetros específicos.


Aunque un const int no siempre será apropiado, una enumeración generalmente funcionará como un sustituto del #define si está definiendo algo como un valor integral. Esta es realmente mi preferencia en tal caso.

enum { FIELD_WIDTH = 16384 }; char buf[FIELD_WIDTH];

En C ++, esta es una gran ventaja, ya que puede definir su enum en una clase o espacio de nombres, mientras que no puede definir un #define.

En C no tienes espacios de nombres y no puedes definir una enumeración dentro de una estructura, y ni siquiera estoy seguro de que tengas la seguridad de tipo, así que no puedo ver ninguna ventaja importante, aunque tal vez algún programador de C me lo indique. .


Ellos son diferentes.

const es solo un calificador, que dice que una variable no se puede cambiar en tiempo de ejecución. Pero todas las demás características de la variable persisten: ha asignado almacenamiento, y este almacenamiento puede abordarse. Así que el código no solo lo trata como un literal, sino que se refiere a la variable accediendo a la ubicación de memoria especificada (excepto si es static const , luego puede optimizarse), y cargando su valor en tiempo de ejecución. Y como una variable const ha asignado almacenamiento, si la agrega a un encabezado y la incluye en varias fuentes C, obtendrá un error de vinculación de "definición de símbolo múltiple" a menos que lo marque como extern . Y en este caso, el compilador no puede optimizar el código contra su valor real (a menos que la optimización global esté activada).

#define simplemente sustituye un nombre por su valor. Además, una constante #define ''d se puede usar en el preprocesador: se puede usar con #ifdef para hacer una compilación condicional en función de su valor, o usar el operador de stringing # para obtener una cadena con su valor. Y como el compilador conoce su valor en tiempo de compilación, puede optimizar el código en función de ese valor.

Por ejemplo:

#define SCALE 1 ... scaled_x = x * SCALE;

Cuando SCALE se define como 1 el compilador puede eliminar la multiplicación, ya que sabe que x * 1 == x , pero si SCALE es una const ( extern ), necesitará generar código para recuperar el valor y realizar la multiplicación porque el valor no se conocerá hasta la etapa de enlace. ( extern es necesario para usar la constante de varios archivos fuente).

Un equivalente más cercano al uso de #define es usar enumeraciones:

enum dummy_enum { constant_value = 10010 };

Pero esto está restringido a valores enteros y no tiene las ventajas de #define , por lo que no se usa ampliamente.

const es útil cuando necesita importar un valor constante desde alguna biblioteca donde se compiló. O si se usa con punteros. O si se trata de una matriz de valores constantes a los que se accede a través de un valor de índice variable. De lo contrario, const no tiene ventajas sobre #define .


Expandir en respuestas de R un poco: fieldWidth no es una expresión constante ; es una variable const calificada. Su valor no se establece hasta el tiempo de ejecución, por lo que no puede utilizarse cuando se requiere una expresión constante en tiempo de compilación (como en una declaración de matriz, o una etiqueta de caja en una instrucción de switch , etc.).

Compare con la macro FIELD_WIDTH , que después del preprocesamiento se expande a la expresión constante 10 ; este valor se conoce en tiempo de compilación, por lo que se puede usar para dimensiones de matriz, etiquetas de casos, etc.


Hay una razón muy sólida para esto: const en C no significa que algo sea constante. Simplemente significa que una variable es de solo lectura.

En lugares donde el compilador requiere una constante verdadera (como por ejemplo para tamaños de matriz para matrices que no son VLA), el uso de una variable const , como fieldWidth simplemente no es posible.


La mejor forma de definir constantes numéricas en C es usando enum . Lea el capítulo correspondiente de The C Programming Language de K & R, página 39.


La razón es que la mayoría de las veces, quieres una constante, no una variable const qualified. Los dos no son remotamente iguales en el lenguaje C. Por ejemplo, las variables no son válidas como parte de los inicializadores para objetos static de duración de almacenaje, como dimensiones de matriz no vla (por ejemplo, el tamaño de una matriz en una estructura o cualquier matriz anterior a C99).


Para agregar a la respuesta de R. y Bart: solo hay una forma de definir constantes de tiempo de compilación simbólicas en C: constantes de tipo de enumeración. El estándar impone que estos son de tipo int . Yo personalmente escribiría tu ejemplo como

enum { fieldWidth = 10 };

Pero creo que ese sabor difiere mucho entre los programadores de C sobre eso.


Según K & R (2ª edición, página 211) las "propiedades const y volátiles son nuevas con el estándar ANSI". Esto puede implicar que el código ANSI realmente antiguo no tenía estas palabras clave en absoluto y realmente es solo una cuestión de tradición. Además, dice que un compilador debe detectar intentos de cambiar las variables const, pero aparte de eso puede ignorar estos calificadores. Creo que esto significa que algunos compiladores pueden no optimizar el código que contiene la variable const para representarse como valor intermedio en el código máquina (como #define) y esto puede costar en tiempo adicional para acceder a la memoria remota y afectar el rendimiento.