#c
Вопрос:
#include <stdio.h>
#define foo(x,y) x/y x
int main()
{
int i=-6,j=3;
printf("%d",foo(i j,3));
}
проблема;
этот код дает ответ -8
разве это не возврат -4 математически .. пожалуйста, объясните ..помогите
Комментарии:
1. Попробуйте скомпилировать свой исходный код,
gcc -E
чтобы увидеть, какi j
он заменяется.
Ответ №1:
foo(x,y)
определяется как x/y x
, поэтому foo(i j,3)
расширяется до i j/3 i j
. Поскольку /
имеет более высокий приоритет , чем
, это эквивалентно i (j / 3) i j
, а не (i j) / 3 i j
так, как вы предположительно предполагали.
Лучшее решение в этом случае-не использовать макрос, а просто написать обычную функцию:
int foo(int x, int y) {
return x / y x;
}
Если по какой-либо причине это не вариант, вам нужно добавить несколько скобок:
#define foo(x,y) ((x) / (y) (x))
. . . но даже это даст странные результаты, если x
у него будут побочные эффекты, потому x
что он расширяется дважды, так что эти побочные эффекты произойдут дважды. (И в некоторых случаях это приведет к неопределенному поведению.)
Комментарии:
1. Кроме того, если вы хотите увидеть, на что расширяется ваш макрос, вы можете использовать
-E
опцию (т. е. arg препроцессора) в gcc в качестве:gcc -E myfile.c -o preproc.c
2. При замене макроса функцией часто лучше объявлять функцию
static inline
, так как это более тесно согласуется с тем , что делает макрос: предоставляет некоторый встроенный код, видимый только в текущей единице перевода. Такint foo(int x, int y)
могло бытьstatic inline int foo(int x, int y)
.
Ответ №2:
Это -8 от того, как работают макросы в C. Во время компиляции все макросы в коде дословно заменяются определением макрокоманды.
Итак, в вашем примере все вхождения foo(x y)
заменяются на x/y x
которые при применении к printf происходит от
printf("%d",foo(i j,3));
Для
printf("%d",i j/3 i j);
которые при замене значениями i и j дают следующее
printf("%d",-6 3/3 -6 3);
И, таким образом, печатается -8.