Die Ausgabe dieses C-Codes ist 49, aber kann mir jemand erklären, wie? [Duplikat]

Jan 20 2021
#include <stdio.h>

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

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

Antworten

5 MarkSouls Jan 20 2021 at 14:31

Das Makro verwandelt den Code in:

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

das ist effektiv:

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

Wenn Sie Würfel wollen 9zu bekommen 729, sollten Sie schreiben CUBE((4+5)).

9 chqrlie Jan 20 2021 at 14:34

So wird das Makro während des Kompilierungsprozesses erweitert:

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

Da dieser Ausdruck *eine höhere Priorität als hat +, wird er als " (4 + (5 * 4) + (5 * 4) + 5)produzierend" 49anstatt als erwartet bewertet 729.

Um solche Probleme mit der Priorität von Operatoren zu vermeiden, müssen alle Makroargumente in der Makrodefinition sowie im Ausdruck selbst in Klammern stehen:

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

Beachten Sie jedoch, dass diese Erweiterung von mehrfach CUBEausgewertet wird. Dies xist ein Problem, wenn das Makroargument Nebenwirkungen hat, wie z CUBE(i++).

Um all diese Probleme zu vermeiden, verwenden Sie eine Funktion und lassen Sie sie vom Compiler optimieren:

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

Sie können static inlinevor dieser Funktionsdefinition hinzufügen , aber moderne Optimierer werden die Funktion ohne diese weiterhin einbinden.

3 Tecto Jan 20 2021 at 14:32

Der C-Präprozessor ersetzt buchstäblich alle Instanzen von x durch 4 + 5, was zu folgendem Code führt:

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

(zuerst Multiplikation, dann Addition)

3 SahadatHossain Jan 20 2021 at 14:31

Sie müssen die Eingabe so geben, als CUBE((4+5))ob Sie die Zahlen hinzufügen und dann an senden möchten CUBE. Denn th CUBE(4+5)wird grundsätzlich erweitert, 4+5*4+5*4+5da es das Ganze 4+5an die Stelle von setzt x. Also, 4+5*4+5*4+5= 4+20+20+5wenn die Multiplikation zuerst kommt und dann addiert wird, ergibt sich 49.

Definieren Sie das Makro so, wie #define CUBE(x) ((x)*(x)*(x))es tatsächlich ist. Führen Sie zuerst die (4+5)Operation für jede aus (x)und führen Sie dann die *Operation aus.

Eine andere Möglichkeit ist, einfach CUBE((4+5))beim Aufrufen des Makros zu verwenden. Grundsätzlich werden zuerst die beiden Zahlen und (4+5)= hinzugefügt 9und dann CUBE(9)wie folgt ausgeführt :

#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

Lesen Moderne C , dann wird der n1570 Entwurf C - Standard, und die Dokumentation von GCC und GDB und der CPP . Siehe auch diese C-Referenzwebsite .

Lassen Sie sich von bestehenden Open Source-Projekten inspirieren, z. B. von Github oder GNU-Software .

Rufen Sie einen aktuellen GCC- Compiler als auf . Verwenden Sie auch die Optionen, um das vorverarbeitete Formular abzurufen.gcc -Wall -Wextra -g-C -E

Sie könnten auch an der Statement-Expr- Erweiterung von GCC interessiert sein .

Ihr CUBE(4+5)ist makroerweitert und 4+5*4+5*4+5wird 4+(5*4)+(5*4)+5gemäß der Priorität der C-Operatoren berechnet .

Erwägen Sie, eine static inlineFunktion wie zu codieren

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

oder wenn Sie zumindest ein Makro benötigen

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

was nicht gut funktioniert CUBE(i++)(während Sie mit der inlineFunktion cube(i++)tun , was Sie wollen: ieinmal erhöhen !).

Übrigens könnten Sie GPP oder GNU m4 (oder Ihren eigenen Generator oder GNU Bison ) verwenden, um C-Code zu generieren. Als Faustregel gilt: Denken Sie mit ASTs : Wenn Sie C-Code generieren, geben Sie viele nutzlose Klammern aus, z. B. in Chicken Scheme , SWIG , CAIA oder my manydl.c

Sie können auch den statischen Analysator Clang für Ihren Code (und möglicherweise Frama-C ) verwenden.

Möglicherweise möchten Sie einige Codierungsrichtlinien wie MISRA C oder GNU lesen .