我在测试中弄错了这个问题,真是很困惑为什么。
对于下面的给定代码,我认为输出为0。有人可以解释为什么不是吗?
#include<iostream>
using namespace std;
#define A 0
#define B A+1
#define C 1-B
int main{
cout<<C;
return(0);
}
正确答案(和实际输出)是2。
答案 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}}。
请记住,A
,B
和C
不是变量。它们是宏-即指向预处理器的有关如何进行文本替换的指南。
答案 2 :(得分:1)
我认为输出为0。有人可以解释为什么 不是吗?
因为C
扩展为1-B
现在,B
扩展为A+1
。
现在,A
再次扩展为0
填补空白:
自A
扩展为0
以来,B
被0+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);
}
优点是:易于使用,因为您已经知道语法和行为。不允许未定义的行为,这使此操作更安全。而且,您不能有循环依赖给人以奇怪的副作用,否则就无法编译。