language - macro function in c
¿Prefiero las constantes sobre las definiciones? (10)
En C, ¿preferiré las constantes sobre las definiciones? He leído mucho código últimamente, y todos los ejemplos hacen uso intensivo de define.
Además de las excelentes razones dadas por AndreyT para usar DEFINES en lugar de constantes en el código "C", hay otra razón más pragmática para usar DEFINES.
DEFINES es fácil de definir y usar desde (.h) archivos de encabezado, que es donde cualquier codificador de C con experiencia esperaría encontrar constantes definidas. Definir constelaciones en los archivos de encabezado no es tan fácil: es más código para evitar definiciones duplicadas, etc.
Además, los argumentos de "tipo seguro" son irrelevantes: la mayoría de los compiladores detectarán errores evidentes tales como asignar una cadena a int, o "harán lo correcto" en una discrepancia leve, como asignar un entero a un flotante.
Aunque esta pregunta es específica de C, creo que es bueno saber esto:
#include<stdio.h>
int main() {
const int CON = 123;
int* A = &CON;
(*A)++;
printf("%d/n", CON); // 124 in C
}
funciona en C , pero no en C ++
Una de las razones para usar #define
es evitar que esas cosas arruinen tu código, especialmente es una mezcla de C y C ++.
Las constantes deben preferirse a las define
. Hay varias ventajas:
Escriba seguridad . Mientras C es un lenguajeged débilmente tipeado, el uso de un
define
pierde todo tipo de seguridad, lo que le permitirá al compilador detectar los problemas por usted.Facilidad de depuración . Puede cambiar el valor de las constantes a través del depurador, mientras que las
define
s se cambian automáticamente en el código por el preprocesador al valor real , lo que significa que si desea cambiar el valor para fines de prueba / depuración, debe volver a compilar.
Las definiciones han sido parte del lenguaje por más tiempo que las constantes, por lo que una gran cantidad de código antiguo las usará porque define dónde está la única forma de hacer el trabajo cuando se escribió el código. Para un código más reciente, puede ser simplemente una cuestión de hábito del programador.
Las constantes tienen un tipo así como también un valor, por lo que se preferirían cuando tiene sentido que su valor tenga un tipo, pero no cuando es sin tipo (o polimórfico).
Las macros (define) pueden ser utilizadas por el pre-procesador y en tiempo de compilación, las constantes no pueden.
Puede hacer comprobaciones en tiempo de compilación para asegurarse de que una macro se encuentre dentro de un rango válido (y #error o #fatal si no lo está). Puede usar valores predeterminados para una macro si aún no se ha definido. Puede usar una macro en el tamaño de una matriz.
Un compilador puede optimizar con macros mejor de lo que puede hacerlo con constantes:
const int SIZE_A = 15;
#define SIZE_B 15
for (i = 0; i < SIZE_A + 1; ++i); // if not optimized may load A and add 1 on each pass
for (i = 0; i < SIZE_B + 1; ++i); // compiler will replace "SIZE_B + 1" with 16
La mayor parte de mi trabajo es con procesadores integrados que no tienen sorprendentes compiladores de optimización. Tal vez gcc trate SIZE_A como una macro en algún nivel de optimización.
Mucha gente aquí te está dando consejos sobre "estilo C ++". Algunos incluso dicen que los argumentos de C ++ se aplican a C. Ese puede ser un buen punto. (Si es o no se siente algo subjetivo.) Las personas que dicen que const
veces significa algo diferente en los dos idiomas también son correctas.
Pero estos son en su mayoría puntos menores y, personalmente, creo que en verdad hay una consecuencia relativamente menor en ir de cualquier manera. Es una cuestión de estilo, y creo que diferentes grupos de personas te darán respuestas diferentes.
En términos de uso común, uso histórico y estilo más común, en C, es mucho más típico ver #define
. El uso de ismos C ++ en código C puede resultar extraño para un cierto segmento estrecho de codificadores C. (Incluyéndome a mí, así que ahí están mis prejuicios).
Pero me sorprende que nadie haya sugerido una solución intermedia, que "se sienta bien" en ambos idiomas: si encaja en un grupo de constantes enteras, use una enum
.
Si es algo que no está determinado por programación, uso #define
. Por ejemplo, si quiero que todos mis objetos UI tengan el mismo espacio entre ellos, podría usar #define kGUISpace 20
.
Tal vez los he estado usando incorrectamente pero, al menos en gcc, no se pueden usar constantes en las sentencias case.
const int A=12;
switch (argc) {
case A:
break;
}
define puede usarse para muchos propósitos (muy sueltos) y debe evitarse si puede sustituirlo por const, que define una variable y puede hacer mucho más con ella.
En casos como los siguientes, define tiene que ser utilizado
- interruptor de direccion
- sustitución a su línea fuente
- macros de código
Un ejemplo donde tiene que usar definir sobre const es cuando tiene el número de versión decir 3 y quiere que la versión 4 incluya algunos métodos que no están disponibles en la versión 3
#define VERSION 4
...
#if VERSION==4
................
#endif
No, en general, no debe usar objetos calificados const en C para crear nombres constantes. Para crear una constante con nombre en C, debe usar macros ( #define
) o enumeraciones. De hecho, el lenguaje C no tiene constantes, en el sentido de que parece implicar. (C es significativamente diferente de C ++ en este sentido)
En lenguaje C, las nociones de expresión constante y constante se definen de forma muy diferente a C ++. En C constante significa un valor literal , como 123
. Aquí hay algunos ejemplos de constantes en C
123
34.58
''x''
Las constantes en C se pueden usar para construir expresiones constantes . Sin embargo, dado que los objetos consti- tuidos de cualquier tipo no son constantes en C, no pueden utilizarse en expresiones constantes y, por lo tanto, no puede usar objetos const const cuando se requieren expresiones constantes.
Por ejemplo, lo siguiente no es una constante
const int C = 123; /* C is not a constant!!! */
y dado que la C
anterior no es una constante, no se puede usar para declarar un tipo de matriz en el alcance del archivo
typedef int TArray[C]; /* ERROR: constant expression required */
No se puede usar como una etiqueta de caso
switch (i) {
case C: ; /* ERROR: constant expression required */
}
No se puede usar como ancho de campo de bits
struct S {
int f : C; /* ERROR: constant expression required */
};
No se puede utilizar como un inicializador para un objeto con una duración de almacenamiento estática
static int i = C; /* ERROR: constant expression required */
No se puede usar como un inicializador enum
enum {
E = C /* ERROR: constant expression required */
};
es decir, no puede usarse en ningún lugar donde se requiera una constante .
Esto puede parecer contra-intuitivo, pero así es como se define el lenguaje.
Es por eso que ve estos numerosos #define
-s en el código con el que está trabajando. De nuevo, en el lenguaje C el objeto const calificado tiene un uso muy limitado. Básicamente son completamente inútiles como "constantes", por lo que en el lenguaje C básicamente estás obligado a usar #define
o enums para declarar constantes verdaderas.
Por supuesto, en situaciones en las que un objeto calificado para const funciona para usted, es decir, hace lo que usted quiere que haga, de hecho es superior a las macros de muchas maneras, ya que tiene un alcance y se escribe. Probablemente prefiera dichos objetos cuando corresponda, sin embargo, en general, tendrá que tener en cuenta las limitaciones anteriores.