La sortie de ce code C est 49 mais quelqu'un peut-il m'expliquer comment? [dupliquer]

Jan 20 2021
#include <stdio.h>

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

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

Réponses

5 MarkSouls Jan 20 2021 at 14:31

Macro transformera le code en:

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

ce qui est effectivement:

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

Si vous voulez 9obtenir un cube 729, vous devez écrire CUBE((4+5)).

9 chqrlie Jan 20 2021 at 14:34

Voici comment la macro est développée pendant le processus de compilation:

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

Parce que *a une priorité plus élevée que +, cette expression est évaluée comme (4 + (5 * 4) + (5 * 4) + 5), produisant 49au lieu de l'attendu 729.

Pour éviter de tels problèmes de priorité des opérateurs, tous les arguments de macro doivent être mis entre parenthèses dans la définition de macro ainsi que dans l'expression elle-même:

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

Notez cependant que cette expansion de CUBEévalue xplusieurs fois, ce qui pose un problème si l'argument macro a des effets secondaires, tels que CUBE(i++).

Pour éviter tous ces problèmes, utilisez une fonction et laissez le compilateur l'optimiser:

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

Vous pouvez ajouter static inlineavant cette définition de fonction, mais les optimiseurs modernes incorporeront toujours la fonction sans cela.

3 Tecto Jan 20 2021 at 14:32

Le préprocesseur C substituera littéralement toutes les instances de x par 4 + 5, ce qui donnera le code suivant:

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

(multiplication d'abord, puis addition)

3 SahadatHossain Jan 20 2021 at 14:31

vous devez donner l'entrée comme CUBE((4+5))si vous voulez ajouter les nombres, puis envoyer à CUBE. Parce que cela CUBE(4+5)est essentiellement étendu à 4+5*4+5*4+5car il place le tout 4+5à la place de x. Donc, 4+5*4+5*4+5= 4+20+20+5comme la multiplication vient en premier, puis les ajouter donnera 49.

Définissez la macro comme si #define CUBE(x) ((x)*(x)*(x))elle procédait d'abord à l' (4+5)opération pour chaque (x), puis effectuez l' *opération.

Une autre façon consiste simplement à utiliser CUBE((4+5))lors de l'appel de la macro, en gros, il a d'abord ajouté les deux nombres et (4+5)= 9puis faites CUBE(9), comme:

#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

Lisez Modern C , puis le projet de norme C n1570 , et la documentation de GCC et de GDB et de CPP . Voir également ce site Web de référence C.

Inspirez-vous des projets open source existants, par exemple sur github ou sur des logiciels GNU .

Avec un compilateur GCC récent , invoquez-le comme gcc -Wall -Wextra -g. Utilisez également les -C -Eoptions pour obtenir le formulaire prétraité.

Vous pourriez également être intéressé par l' extension statement-expr de GCC.

Votre CUBE(4+5)est macro-expansion à 4+5*4+5*4+5laquelle est calculée comme 4+(5*4)+(5*4)+5fonction de la priorité des opérateurs C .

Pensez à coder une static inlinefonction comme

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

ou si vous avez besoin d'une macro, au moins

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

ce qui ne fonctionnera pas bien pour CUBE(i++)(alors qu'avec la inlinefonction, cube(i++)fait ce que vous voulez qu'elle fasse: incrémenter iune fois!).

BTW, vous pouvez utiliser GPP , ou GNU m4 , (ou votre propre générateur, ou GNU bison ) pour générer du code C. En règle générale, pensez avec les AST : lorsque vous générez du code C, émettez beaucoup de parenthèses inutiles, comme par exemple dans Chicken Scheme , SWIG , ou dans CAIA ou dans mon manydl.c

Vous pouvez également utiliser l' analyseur statique Clang sur votre code (et peut - être Frama-C ).

Vous pourriez être intéressé par la lecture de quelques directives de codage comme celles de MISRA C ou GNU .