2015-08-09 12 views

Antwort

6

Nach der Vorverarbeitung der printf Linie sein wird:

printf("%d",64/4*4); 

was erklären sollte, warum es 64 druckt.

Verwenden Sie immer Klammern in Makros Definitionen, wenn sie Ausdrücke enthalten:

#define sqr(a) ((a)*(a)) 

Auch diese gegen Makro Anrufungen nicht sicher ist, wie: sqr(x++). Also verwende keine Marcos, außer du musst :)

0

Makros sind keine Funktionen, sie sind (meist) dummer Textersatz. Ihr Makro fehlt Klammern, also wenn die preprocesor es ersetzt, dann würden Sie das folgende erhalten:

printf("%d",64/4*4); 

Seit / und * haben die gleiche Priorität, das ist wie die besagt (64/4)*4, das ist, natürlich, 64.

Wenn Sie Ihr sqr Makro wollen sicher sein Argument zu quadrieren, wickeln Sie es in Klammern:

#define sqr(a) (a*a) 
0

64/sqr(4) wird 64/4*4 erweitert.

Sie haben die Makro Körper parenthetise und sollte auch setzen Klammern das Argument aroud:

#define sqr(a) ((a)*(a)) 

Ausbeuten: 64/(4*4)

Beachten Sie, dass Makros rein sind Text Ersatz durch den Präprozessor C durchgeführtvor beginnt die eigentliche Kompilierung.

Ein besserer und typsichere Ansatz wäre eine inline Funktion zu verwenden:

static inline int sqr(int a) 
{ 
    return a * a; 
} 

Diese wahrscheinlich inlined vom Compiler in den Anrufercode wird so viel wie das Makro wäre. OTOH, könnte der Compiler sehr gut entscheiden, nicht, abhängig von internen Heuristiken. Im Allgemeinen sollten Sie dem Compiler vertrauen, den richtigen Weg zu wählen, es sei denn, Sie haben schwerwiegende Probleme mit der Leistung/Code-Größe.

Dies schützt auch vor der zweimaligen Auswertung des Arguments a. Das ist entscheidend, wenn es Nebenwirkungen wie

int i[2], *p = i; 
sqr(*p++); 

Für die Makro-Version, diese in nicht definiertes Verhalten (undefined Reihenfolge der Auswertung) führen wird:

((*p++) * (*p++)) 
Verwandte Themen