Квадрат числа определяется с помощью #define

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

Я совершенно смущен этим,

#include  #include  #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 !!?

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()) вызывает функцию дважды и поэтому не обязательно вычисляет квадрат, а скорее продукт двух последовательных вызовов, конечно ;-).

Когда вы пишете 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 .

 i=4/square(4); 

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

 i=4/4*4; 

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

 i=(4/4)*4; 

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

Макрос расширяется предварительным процессором таким образом, что

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

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

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

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

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

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

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

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

Вручную развернуть макрос в коде, и это будет ясно. То есть, замените весь квадрат (x) ровно x * x, в частности, не добавляйте никаких круглых скобок.

define – это просто текстовый макрос

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

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

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

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

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

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

 #define square(x) (x*x) 

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

 #define square(x) (x*x) 

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

  • Как работает getchar ()?
  • Возвращаемое значение оператора «==» в C
  • Почему мы должны инициализировать переменную перед ее использованием?
  • Загадка (в C)
  • локальная переменная, инициализированная нулем в C
  • Является ли fmod () точным, когда y является целым числом?
  • Каков эффективный способ подсчета бит в позиции или ниже?
  • Практическое использование setjmp и longjmp в C
  • Я могу использовать больше памяти, чем то, что я выделил с помощью malloc (), почему?
  • интеграция пружин + cron + кварц в кластере?
  • Присвоение отрицательных чисел неподписанному int?
  • Interesting Posts

    Включить файлы заголовков с помощью командной строки?

    Как реализовать навигационную кнопку в общих ресурсах приложений?

    Как изменить ассоциации файлов на Mac OS X?

    OnClickListener не отвечает

    Что такое LD_LIBRARY_PATH и как его использовать?

    HTML5 Video не работает с тегом AngularJS ng-src

    Windows 7 двойной монитор, при открытии приложения, как контролировать, какой монитор пользовательский интерфейс приложения будет отображаться?

    У меня есть «неизвестное устройство PCI» в диспетчере устройств Windows 7. Что это может быть?

    Сообщение об ошибке при запуске терминала

    Как доверенный корневой сертификат появляется в списке доверенных корней?

    Воспроизведение фильмов DVD в Windows 8

    Как связать MemoryStream с asp: управление изображениями?

    Создайте токен доступа «никогда не истекающий» для страницы Facebook

    Алгоритм определения игры Tic Tac Toe Over

    Исправить карточку SD, которая сообщает слишком большой размер?

    Давайте будем гением компьютера.