2010-09-15 3 views
9

Ich habe gerade einen bestimmten Code durchgelesen, der häufig in Interviews gefragt wird. Ich habe bestimmte Fragen gestellt, ob mir jemand dabei helfen kann?Das Quadrat einer Nummer wird definiert mit #define

Ich bin total verwirrt auf diese jetzt,

#include <stdio.h> 
#include <conio.h> 

#define square(x) x*x 

main() 
{ 
     int i, j; 
     i = 4/square(4); 
     j = 64/square(4); 
     printf("\n %d", i); 
     printf("\n %d", j); 
     printf("\n %d", square(4)); 
     getch(); 
} 

Die Ausgabe lautet:

4 
64 
16 

Ich frage mich, warum hat square(4) Rückkehr 1, wenn ich es geteilt? Ich meine, wie kann ich den Wert 4 und 64 bekommen, wenn ich es teile, aber wenn direkt verwendet bekomme ich !!?

+1

Nur um zu bemerken, dass #define square (x) x * x ist eine klassische C bady. Probieren Sie eine Schleife mit Quadrat (x ++); – Jaydee

+5

Wenn du dich wirklich verwirren willst und noch keine der Antworten gelesen hast, versuche, 'square (4)' überall mit 'square (3 + 1)' zu ersetzen. – JeremyP

+0

Dies war ein einfaches Präzedenzproblem. –

Antwort

26

square ist under-geklammert: es textlich erweitert, so

#define square(x) x*x 
    ... 
i=4/square(4); 

bedeutet

i=4/4*4; 

welche Gruppen als (4/4) * 4.Um dies zu beheben, fügen Sie Klammern:

#define square(x) ((x)*(x)) 

immer noch eine sehr zweifelhafte #define wie es x zweimal auswertet, so square(somefun()) die Funktion zweimal aufruft und tut nicht daher notwendigerweise ein Quadrat berechnen, sondern das Produkt der beiden aufeinanderfolgenden Anrufe, Na sicher;-).

+0

ja .. habe es .. wurde verrückt darüber .. –

+3

+1 für 'Quadrat (Somefun())'. Die übliche Beobachtung in diesem Fall ist eine zweifache Nebenwirkung, aber wenn man sich 'Quadrat (rand()) 'vorstellt, erhält man das Produkt zweier Zufallszahlen, nicht das Quadrat einer einzelnen Zufallszahl. – RBerteig

2

Operator Priorität ist Ihnen weh.

Das Makro durch den Präprozessor erweitert wird, so dass

i=4/4*4; 
    j=64/4*4; 

was äquivalent ist:

i=(4/4)*4; 
    j=(64/4)*4; 
1

j = 4/square(4) == 4/4*4 == 1*4 == 4

4

Wenn Sie i=4/square(4) schreiben, dehnt sich der Prä-Prozessor, das zu i = 4/4 * 4 .
Da C Operationen von links nach rechts gruppiert, interpretiert der Compiler das als i = (4/4) * 4, was 1 * 4 entspricht.

Sie müssen Klammern hinzuzufügen, wie folgt aus:

#define square(x) ((x)*(x)) 

Auf diese Weise i=4/square(4) verwandelt sich in i = 4/((4) * (4)).
Sie benötigen die zusätzlichen Klammern um x für den Fall, dass Sie schreiben square(1 + 1), die sonst in 1 + 1 * 1 + 1, die als 1 + (1 * 1) + 1 oder 3 ausgewertet wird.

3
i=4/square(4); 

expandiert nach

i=4/4*4; 

die äquivalent zu

i=(4/4)*4; 
0

manuell das Makro im Code erweitern, und es wird klar sein. Das heißt, ersetzen Sie das ganze Quadrat (x) durch genau x * x, insbesondere fügen Sie keine Klammern hinzu.

0

definieren ist nur ein Text Makro

main() 
{ 
     int i,j; 
     i=4/ 4 * 4; // 1 * 4 
     j=64/4 * 4; // 16 * 4 
     printf("\n %d",i); 
     printf("\n %d",j); 
     printf("\n %d",square(4)); 
     getch(); 
} 
0

Es ist ein Makro! So gibt es genau zurück, was es ersetzt.

i = 4/4*4; Which is 4... 
j = 64/4*4; Which is 16... 

Versuchen Sie dies für Ihr Makro:

#define square(x) ((x)*(x)) 
0

Wegen Operatorpräzedenz im Ausdruck nach dem Prä-Prozessor - Sie werden

#define square(x) (x*x) 
0

schreiben müssen, wie die anderen Antworten sagen, Sie werden von der Priorität des Operators gebrannt. Ändern Sie Ihr quadratisches Makro zu diesem:

#define square(x) (x*x) 

und es wird funktionieren, wie Sie erwarten.

2

Das ist, weil der Compiler mit ersetzt:

i=4/4*4; 
j=64/4*4; 

i = (4/4) * 4 = 1 * 4 = 4.

j = (64/4) * 4 = 16 * 4 = 64.

Verwandte Themen