La salida de este código C es 49, pero ¿alguien puede explicarme cómo? [duplicar]

Jan 20 2021
#include <stdio.h>

#define CUBE(x) (x * x * x)

int main() {
    printf("%d", CUBE(4+5));
    return 0;
}

Respuestas

5 MarkSouls Jan 20 2021 at 14:31

Macro cambiará el código a:

printf("%d", (4+5 * 4+5 * 4+5));

que es efectivamente:

printf("%d", 4 + (5*4) + (5*4) + 5); // 29

Si desea 9obtener un cubo 729, debe escribir CUBE((4+5)).

9 chqrlie Jan 20 2021 at 14:34

Así es como se expande la macro durante el proceso de compilación:

printf("%d", (4+5 * 4+5 * 4+5));

Dado que *tiene una precedencia mayor que +, esta expresión se evalúa como (4 + (5 * 4) + (5 * 4) + 5), produciendo en 49lugar de lo esperado 729.

Para evitar estos problemas de precedencia de operadores, todos los argumentos de macro deben estar entre paréntesis en la definición de macro, así como en la expresión en sí:

#define CUBE(x)  ((x) * (x) * (x))

Sin embargo , tenga en cuenta que esta expansión de se CUBEevalúa xvarias veces, lo cual es un problema si el argumento macro tiene efectos secundarios, como CUBE(i++).

Para evitar todos estos problemas, use una función y deje que el compilador la optimice:

int cube(int x) {
    return x * x * x;
}

Puede agregar static inlinedelante de esta definición de función, pero los optimizadores modernos seguirán incorporando la función sin esto.

3 Tecto Jan 20 2021 at 14:32

El preprocesador de C sustituirá literalmente todas las instancias de x por 4 + 5, lo que dará como resultado el siguiente código:

i = 4+5*4+5*4+5;

(multiplicación primero, luego suma)

3 SahadatHossain Jan 20 2021 at 14:31

debe dar la entrada como CUBE((4+5))si desea agregar los números y luego enviar a CUBE. Porque CUBE(4+5)básicamente se expande a 4+5*4+5*4+5cuando coloca el todo 4+5en el lugar de x. Entonces, 4+5*4+5*4+5= 4+20+20+5ya que la multiplicación viene primero y luego sumarlos dará 49.

Defina la macro como #define CUBE(x) ((x)*(x)*(x))en realidad, primero proceda con la (4+5)operación para todos (x)y luego realice la *operación.

Otra forma es usarlo CUBE((4+5))mientras se llama a la macro, básicamente primero agregó los dos números y (4+5)= 9y luego lo hizo CUBE(9), como:

#include<stdio.h>
#define CUBE(x) (x * x * x)

int main( )
{
    printf("%d", CUBE((4+5)));
    return 0;
}
1 BasileStarynkevitch Jan 20 2021 at 14:29

Lea Modern C , luego el borrador del estándar C n1570 , y la documentación de GCC y de GDB y de CPP . Consulte también este sitio web de referencia de C.

Inspírate en proyectos de código abierto existentes, por ejemplo, en github o software GNU .

Con un compilador GCC reciente , invocalo como gcc -Wall -Wextra -g. Utilice también las -C -Eopciones para obtener el formulario preprocesado.

También podría interesarle la extensión statement-expr de GCC.

Su CUBE(4+5)es-macro expandido para 4+5*4+5*4+5que se calcula como 4+(5*4)+(5*4)+5de acuerdo con la precedencia de operadores C .

Considere codificar una static inlinefunción como

static inline int cube(int x) { return x*x*x; }

o si necesitas una macro, al menos

#define CUBE(X) ((X)*(X)*(X))

que no funcionará bien CUBE(i++)(mientras que con la inlinefunción, cube(i++)hace lo que quieres que haga: ¡incrementar iuna vez!).

Por cierto, puede usar GPP o GNU m4 (o su propio generador, o GNU bison ) para generar algo de código C. Como regla general, piense con AST s: cuando genera código C, emite muchos paréntesis inútiles, como por ejemplo en Chicken Scheme , SWIG o en CAIA o en my manydl.c

También puede usar el analizador estático Clang en su código (y tal vez Frama-C ).

Puede que le interese leer algunas pautas de codificación como MISRA C o GNU .