Как круглые скобки в этом C-коде делают результат таким разным? - PullRequest
0 голосов
/ 08 февраля 2012

Выход для этого кода:

#define RECIPROCAL_1(x)     1/(x)
#define RECIPROCAL_2(x)     1/x

main()
{
  float x=8.0, y;
  y = RECIPROCAL_1(x+10.0);
  printf("1/%3.1f = %8.5f\n", x, y);
  y = RECIPROCAL_2(x+10.0);
  printf("1/%3.1f = %8.5f\n", x, y);
}

выводится =

1/8.0 =  0.05556
1/8.0 = 10.12500

Я не вижу, как это работает. Я ценю любые советы.

Ответы [ 3 ]

5 голосов
/ 08 февраля 2012

Подстановки макросов расширены следующим образом:

y = RECIPROCAL_1(x+10.0)

становится

y = 1/(x+10.0);

и

y = RECIPROCAL_2(x+10.0)

становится

y = 1/x+10.0;

Поскольку / имеет более высокий приоритет, чем +, значения для y отличаются.

Это отличный пример того, почему проницательный программист достигает макросов только тогда, когда ни одно другое решение не является жизнеспособным. И даже в этом случае те проницательные программисты, которые считают необходимым использовать макросы, всегда будут использовать достаточные скобки, чтобы избежать таких ловушек.

2 голосов
/ 08 февраля 2012

Развернем макросы:

y = 1/(x + 10)

против

y = 1/x + 10

Способ, которым приоритет оператора выполняется в C, делитель выполняется перед сложением, делая # 2 (1 / x) + 10 вместо 1 / (x + 10). Вот почему вы всегда должны заключать в скобки свои макросы.

2 голосов
/ 08 февраля 2012

Макросы просто выполняют очень простую замену токена, поэтому

#define RECIPROCAL_2(x)     1/x
  y = RECIPROCAL_2(x+10.0);

эквивалентно

  y = 1/x+10.0;
...