2013-06-12 7 views
14

To pytanie zadano mi w pozorowanej wywiadzie ... Naprawdę mam zaskoczeni niewygodnych odpowiedzi ...Mylić przez kwadratury makro SQR wc

rozważyć makro:

#define SQR(x) (x*x) 

Przykład 1:

SQR(2) //prints 4 

Przykład 2:

Jeśli SQR (1 + 1) jest podana nie sumują (1+1) do 2 ale raczej ...

SQR(1+1) //prints 3 

Awkward prawo? Jaki jest powód? Jak działa ten kod?

UWAGA: Szukałem SO, ale nie mogłem znaleźć żadnych istotnych pytań. Jeśli są uprzejmi, prosimy o podzielenie się nimi!

+5

Hint : Czytaj wynik procesora ** pre **. – SLaks

+12

'SQR (1 + 1)' rozwiń na '(1 + 1 * 1 + 1)' == 3, zmień na ((x) * (x)) – BLUEPIXY

+0

To jest preprocesor C. Możesz osiągnąć to samo zachowanie, jeśli używałeś preprocesora C z dowolnym językiem. – user7116

Odpowiedz

45

SQR(1+1) rozwija się do 1+1*1+1 co 3, nie 4, prawda?

Poprawne zdefiniowanie makra będzie

#define SQR(x) ((x)*(x)) 

który rozszerza się (1+1)*(1+1) i ważniejsze, pokazuje jeden z powodów, nie należy korzystać z makr, gdy nie są potrzebne. Dodaje się lepiej:

inline int SQR(int x) 
{ 
    return x*x; 
} 

ponadto: SQR(i++) będzie niezdefiniowane zachowanie jeśli SQR jest makro i całkowicie prawidłowe jeśli SQR jest funkcją.

+3

Oczywiście, nawet "poprawione" makro może wciąż zaskakiwać, gdy dwukrotnie analizuje argument. –

+0

@MikeSeymour to, co miałeś na myśli? –

6

Problemem jest to, że makra robią tekstową substition zanim zostanie skompilowany, więc makro rozwija się do 1+1*1+1

6

To dlatego zawsze put argumenty makra do():

#define SQR(x) ((x)*(x))