A saída deste código C é 49, mas alguém pode me explicar como? [duplicado]

Jan 20 2021
#include <stdio.h>

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

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

Respostas

5 MarkSouls Jan 20 2021 at 14:31

A macro transformará o código em:

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

que é efetivamente:

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

Se você quiser cubo 9para chegar 729, você deve escrever CUBE((4+5)).

9 chqrlie Jan 20 2021 at 14:34

Aqui está como a macro é expandida durante o processo de compilação:

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

Como *tem uma precedência maior que +, essa expressão é avaliada como (4 + (5 * 4) + (5 * 4) + 5), produzindo em 49vez do esperado 729.

Para evitar tais problemas de precedência do operador, todos os argumentos da macro devem estar entre parênteses na definição da macro, bem como na própria expressão:

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

Observe, entretanto, que essa expansão de CUBEavalia xvárias vezes, o que é um problema se o argumento da macro tiver efeitos colaterais, como CUBE(i++).

Para evitar todos esses problemas, use uma função e deixe o compilador otimizá-la:

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

Você pode adicionar static inlineantes desta definição de função, mas os otimizadores modernos ainda incorporarão a função sem isso.

3 Tecto Jan 20 2021 at 14:32

O pré-processador C irá substituir literalmente todas as instâncias de x por 4 + 5, resultando no seguinte código:

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

(multiplicação primeiro, depois adição)

3 SahadatHossain Jan 20 2021 at 14:31

você precisa fornecer a entrada, como CUBE((4+5))se deseja adicionar os números e enviar para CUBE. Porque isso CUBE(4+5)é basicamente expandido para uma 4+5*4+5*4+5vez que coloca o todo 4+5no lugar de x. Portanto, 4+5*4+5*4+5= 4+20+20+5como a multiplicação vem primeiro e depois a adição deles dará 49.

Defina a macro como #define CUBE(x) ((x)*(x)*(x))se realmente procedesse primeiro a (4+5)operação para cada (x)e, em seguida, faça a *operação.

Outra maneira é apenas usar CUBE((4+5))ao chamar a macro, basicamente, primeiro adicionou os dois números e (4+5)= 9e depois fez 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

Leia Modern C , depois o esboço do padrão C n1570 e a documentação do GCC e do GDB e do CPP . Veja também este site de referência C.

Inspire-se em projetos de código aberto existentes, por exemplo, no github ou software GNU .

Com um compilador GCC recente , execute-o como gcc -Wall -Wextra -g. Use também as -C -Eopções para obter o formulário pré-processado.

Você também pode se interessar pela extensão declaração-expr do GCC.

Seu CUBE(4+5)é macro-expandiu-se para 4+5*4+5*4+5o que é computado como 4+(5*4)+(5*4)+5de acordo com a precedência de operadores C .

Considere codificar uma static inlinefunção como

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

ou se você precisa de uma macro, pelo menos

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

que não funcionará bem CUBE(i++)(enquanto com a inlinefunção, cube(i++)faz o que você quer: incrementar iuma vez!).

BTW, você poderia usar GPP , ou GNU m4 , (ou seu próprio gerador, ou GNU bison ) para gerar algum código C. Como regra geral, pense com AST s: quando você gerar código C, emita muitos parênteses inúteis, como, por exemplo, em Chicken Scheme , SWIG , ou em CAIA ou em my manydl.c

Você também pode usar o analisador estático Clang em seu código (e talvez Frama-C ).

Você pode estar interessado em ler algumas diretrizes de codificação como as do MISRA C ou GNU .