#define 宏不如预期
#define macro doesn't as expect
本文关键字:#define 更新时间:2023-10-16
我在测试中弄错了这个问题,真的很困惑为什么。
对于下面的给定代码,我认为输出将为 0。有人可以解释为什么不是吗?
#include<iostream>
using namespace std;
#define A 0
#define B A+1
#define C 1-B
int main{
cout<<C;
return(0);
}
正确答案(和实际输出(是 2。
如果您逐步扩展宏,您将获得正确答案。
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.
预处理器通过执行文本替换和生成随后编译的代码来扩展宏。 预处理器(大多数(不理解表达式 - 由编译的后期阶段(预处理器完成后(处理。
所以C
扩展到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
。
请记住,A
、B
和C
不是变量。 它们是宏 - 即指向预处理器的有关如何进行文本替换的说明。
我以为输出会是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
宏是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);
}
优点是:更易于使用,因为您已经知道语法和行为。不允许未定义的行为,这使得这更安全。而且你不能让循环依赖产生奇怪的副作用,否则它不会编译。
相关文章:
- 与C代码相比,为什么C++代码不需要"#define _POSIX_C_SOURCE 200809L"?
- 以下 C++ 代码用于 -> "#define idiv(a, b) (((a) + (b) / 2) / (b))" 是什么?
- 如何以静态代码分析友好的方式使用 #define 防护?
- C++相当于整数的 #define
- #define Dbg(fmt,..) (0) 是什么意思? 警告:表达式无效
- 在C++中使用变量而不是"#define"来指定数组大小是不是一种糟糕的做法?(C错误:在文件范围内
- 我们可以用 C 语言嵌套 #define 和 #if 吗?
- 如何将旧的 C 样式 #define 映射与现代C++进行调整?
- 找不到 #define 的函数定义
- "#define X X"是什么意思?
- 使用 constexpr 替换 #define 和 #ifdef 进行条件编译
- 野牛/flex:计算器将双精度值解释为整数,所以我添加了 YYSTYPE 双精度 #define 但我有多个编译错误
- 如何解决C++中声纳库贝静态代码分析错误"Explicitly define the missing copy constructor, move constructor .."
- c中 #define 的不足
- 使用 [#define & #ifdef] 跨文件激活代码块
- 如何避免#define语法的变量重新声明
- 使用 GCC 对 C 文件进行部分预处理(不删除 "define" 指令)
- 使用 #define 声明函数
- #define 宏中的括号失败
- 初始化在类类型 #define 中定义的非静态成员数组,不带默认 ctor