#define宏与预期不符

时间:2019-08-17 23:49:52

标签: c++

我在测试中弄错了这个问题,真是很困惑为什么。

对于下面的给定代码,我认为输出为0。有人可以解释为什么不是吗?

#include<iostream>
using namespace std;

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

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

正确答案(和实际输出)是2。

4 个答案:

答案 0 :(得分:7)

如果逐步扩展宏,将会得到正确的答案。

cout<<C;

cout<<1-B;

cout<<1-A+1;

cout<<1-0+1;

cout << 2;

请记住,宏不能像变量一样工作。如果使用变量,则会得到不同的答案。

int a = 0;
int b = a+1;  // b is 1.
int c = 1-b;  // c is 0
cout << c;    // Expect 0 in output.

答案 1 :(得分:1)

预处理器通过执行文本替换并生成随后进行编译的代码来扩展宏。预处理器(大多数情况下)不理解表达式-表达式是由后期编译阶段(在完成预处理器之后)处理的。

因此,1-B扩展为1-A+1,扩展为1-0+1,扩展为1-0+1

这被编译器视为表达式。 2给出#define A 0 #define B (A+1) #define C (1-B)

要获得期望的结果(零),您需要使用

C

因此(1-B)扩展为(1-(A+1)),扩展为(1-(0+1)),扩展为0,其被表达式(由编译器而不是预处理器)作为表达式求值并给出{ {1}}。

请记住,ABC不是变量。它们是宏-即指向预处理器的有关如何进行文本替换的指南。

答案 2 :(得分:1)

  

我认为输出为0。有人可以解释为什么   不是吗?

因为C扩展为1-B

现在,B扩展为A+1

现在,A再次扩展为0


填补空白:

A扩展为0以来,B0+1取代

然后将表达式B中的1-B替换为1-0+1

  C = 1-B
//    ^^^
//      A+1
//      ^^^
//
//  = 1-0+1

答案 3 :(得分:0)

C89,c ++ 11都是宏,因此在编译时提供了一个更好的解决方案:constexpr。

#include<iostream>
using namespace std;

constexpr auto A = 0;
constexpr auto B = A + 1;
constexpr auto C = 1 - B;

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

优点是:易于使用,因为您已经知道语法和行为。不允许未定义的行为,这使此操作更安全。而且,您不能有循环依赖给人以奇怪的副作用,否则就无法编译。