Почему этот макрос дает 2? - PullRequest
2 голосов
/ 02 июля 2019

В настоящее время я изучаю синтаксис C ++ и компиляторы для моего экзамена.

Я готовился к тесту C ++ Mock, чтобы подготовиться к предстоящему экзамену, и натолкнулся на вопрос: «Каков вывод следующего кода?»

#include <iostream>
using namespace std;

#define A    0
#define B    A+1
#define C    1-B

int main() {
    cout << C;
    return 0;
}

Может кто-нибудь объяснить мне, почему код выводит 2 , а не 0 ?

Ответы [ 3 ]

5 голосов
/ 02 июля 2019

B расширен до 0+ 1 и C расширен до 1- 0+ 1, что объясняет результат.

Было бы другое дело, если бы вы написали

#define B    (A+1)

Это хорошая причина избегать макросов.Они в основном не нужны в C ++: шаблоны и методы constexpr являются гораздо лучшими заменами.

3 голосов
/ 02 июля 2019

Небольшое дополнение к ответу @ Bathsheba'a: если вы хотите отладить такую ​​проблему препроцессора, может быть полезно выделить интересную часть в отдельном файле:

// test.cpp

#define A    0
#define B    A+1
#define C    1-B

C;

и отобразить файлпосле предварительной обработки, например, через

g++ -E test.cpp

, что дает (на моей машине)

# 1 "test.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.cpp"

1-0 +1;

Обратите внимание, что важно удалить включенные здесь, например, <iostream> делаетвывод довольно непригодный.

0 голосов
/ 02 июля 2019

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

C

дает

1-B

, что

1-A+1

что составляет

1-0+1

, что составляет 2.

Еще одна вещь, которую нужно иметь в виду, это то, что когда тест запрашивает вывод какого-то неясного фрагмента кода, очевидный ответ, вероятно, не верен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...