Квадрат числа, определяемого с помощью #define - PullRequest
10 голосов
/ 15 сентября 2010

Я просто просматривал определенный код, который часто спрашивают в интервью. У меня возникли определенные вопросы, может ли кто-нибудь помочь мне в этом?

Я сейчас совершенно запутался,

#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();
}

Вывод:

 4
 64
 16

Мне интересно, почему square(4) вернул 1, когда я его разделил? Я имею в виду, как я могу получить значения 4 и 64 , когда я делю его, но при непосредственном использовании я получаю 16 !!?

Ответы [ 11 ]

29 голосов
/ 15 сентября 2010

square заключено в скобки: текст расширяется, поэтому

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

означает

i=4/4*4;

, который группируется как (4/4) * 4.Чтобы исправить, добавьте скобки:

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

Все еще очень ненадежно #define, поскольку он оценивает x дважды, поэтому square(somefun()) вызывает функцию дважды и делает не , поэтому обязательно вычисляетквадрат, а скорее произведение двух последовательных вызовов, конечно; -).

5 голосов
/ 15 сентября 2010

Когда вы пишете i=4/square(4), препроцессор расширяет его до i = 4 / 4 * 4.
Поскольку C группирует операции слева направо, компилятор интерпретирует это как i = (4 / 4) * 4, что эквивалентно 1 * 4.

Вам необходимо добавить круглые скобки, например:

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

Таким образом, i=4/square(4) превращается в i = 4 / ((4) * (4)).
Вам нужны дополнительные скобки вокруг x на случай, если вы напишите square(1 + 1), что в противном случае превратилось бы в 1 + 1 * 1 + 1, что оценивается как 1 + (1 * 1) + 1 или 3.

4 голосов
/ 15 сентября 2010
i=4/square(4);

расширяется до

i=4/4*4; 

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

i=(4/4)*4;
3 голосов
/ 15 сентября 2010

Это потому, что компилятор заменяет его на:

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

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

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

3 голосов
/ 15 сентября 2010

Приоритет оператора причиняет вам боль.

Макрос расширяется препроцессором, так что

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

, что эквивалентно:

  i=(4/4)*4;
  j=(64/4)*4;
2 голосов
/ 15 сентября 2010

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

1 голос
/ 15 сентября 2010

Как говорят другие ответы, вы перегорели из-за приоритета оператора. Измените свой квадратный макрос на это:

#define square(x) (x*x)

и все будет работать так, как вы ожидаете.

1 голос
/ 15 сентября 2010

Из-за приоритета оператора в выражении после препроцессора - вам нужно написать

#define square(x) (x*x)
1 голос
/ 15 сентября 2010

Это макрос!Таким образом, он возвращает точно то, что заменяет.

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

Попробуйте это для своего макроса:

#define square(x) ((x)*(x))
1 голос
/ 15 сентября 2010

определить это просто текстовый макрос

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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...