Frage

HALLO,

Kann jemand mir helfen, zu verstehen, warum der Wert von SQUARE (x) ist 49?

Ich bin mit Visual C ++ 6.0.

#define SQUARE(X) X * X

int main(int argc, char* argv[])
{
    int y = 5;

    printf("%d\n",SQUARE(++y));
    return 0;
}
War es hilfreich?

Lösung

Neil Butterworth, Mark und Pavel recht.

SQUARE (++ y) erweitert y * y ++ ++ auf, die Inkremente den doppelten Wert von y.

Ein weiteres Problem auftreten könnte: SQUARE (a + b) expandiert nach a + b * a + b der nicht (a + b) * (a + b), aber a + (b * a) + b. Sie sollten Klammern um Elemente hinzuzufügen, wenn nötig kümmern, während Makros zu definieren: #define SQUARE (X) ((X) * (X)) etwas weniger riskant ist. (Ian Kemp schrieb er zuerst in seinem Kommentar)

Sie könnten stattdessen eine Inline-Template-Funktion verwenden (nicht weniger effizient zur Laufzeit) wie diese:

template <class T>
inline T square(T value)
{
    return value*value;
}

Sie können überprüfen, es funktioniert:

int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;

(keine Notwendigkeit zu schreiben

square<int>(++i)

, da der int-Typ ist implizit für i)

Andere Tipps

Da die Makro erweitert sich zu:

++y * ++y

, die nicht definiertes Verhalten in C ++ gibt - das Ergebnis konnte alles sein. Dieses sehr gut bekannte Problem sollte in jedem anständigen Lehrbuch abgedeckt werden, die die Verwendung von Makros abdeckt. Welches sind Sie mit?

Da Makros textlicher Substituierung tun so dass der Code, den Sie wird zu schrieb erweitert

printf("%d\n",++y * ++y );

und dann die Reihenfolge der Operationen ist nicht definiertes Verhalten so ist dies der Compiler 2 Schritte sieht und dann eine Multiplikation

Seien Sie also vorsichtig mit Makros besser zu bedienende Funktionen, die als Compiler erweitern kann inline wird nicht mehr in Anspruch nehmen.

Zum anderen gehen nicht davon aus, was passieren wird, wenn Sie erhöhen und die Verwendung Variablen

Makros sind keine Funktionen: sie einfach den Text des Programms ändern. Dieser Vorgang wird als Vorverarbeitung und es wird automatisch ausgeführt, bevor Sie Ihren Code kompiliert wird. Die Leute schreiben Makros ihre Zeit zu sparen und eine gewisse Variabilität zu ihrem Quellcode einzuführen.

Wenn Sie SQUARE(x) schreiben, kein tatsächlicher funciton Aufruf geschieht, nur der Text geändert wird. Die Bedienung ist ganz stumm, so dass Sie zusätzliche Vorsichtsmaßnahmen in Fällen wie dem Ihren zu tun haben. Siehe andere Antworten zur Erläuterung Ihres Falles.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top