我尝试制作应该在参数中交换值的makro。我的代码:
#include <iostream>
using namespace std;
#define swap(x,y) \
x = x * y; \
y = x / y; \
x = x / y;
int main() {
int a = 1;
int b = 2;
swap(a,b);
cout << "a: " << a << ", b: " << b << endl; // a = 2 and b = 1
system("pause");
return 0;
}
我是C ++新手,任何人都可以告诉我为什么我不能这样做?
答案 0 :(得分:3)
你不能这样做,因为当扩展宏时,“参数”将被替换为,而不是。所以展开时你的宏看起来像
2 = 2 * 4;
4 = 2 / 4;
2 = 2 / 4;
换句话说,您尝试将值赋给值,这没有任何意义。
一种解决方案是使用变量,但我建议的是避免使用预处理器宏开始,而是创建一个inline
函数来“正确”执行此操作。或者,您知道,只需使用std::swap
。
哦,还有一件事:你说你想“在预处理器中交换两个数字”。这不可能。预处理器不进行任何操作,它只是将宏调用替换为宏的主体,以创建编译器看到的代码并编译成可执行代码,因此您所做的计算无论如何都是在运行时完成的。如果您想在编译时执行某些操作(但不是由预处理器执行),那么您应该查看 templates 和constexpr
。
答案 1 :(得分:3)
std::swap
做你想做的事。
如果您的任务确实是为此编写宏,请编写一个使用该函数的宏。但要做好准备,你的老师可能不喜欢这个解决方案。
#define swap(x, y) std::swap(x, y)
如果您想避免使用std::swap
,您还可以将元组(x, y)
指定给(y, x)
:
#define swap(x, y) std::tie(y, x) = std::make_tuple(x, y)
答案 2 :(得分:1)
我不确定问题是什么,但你应该考虑到计算机一般不适用于正确的数学概念,而是更受限制的东西。当您使用int
时,它不是整数,而是在某个受限范围内保存值的变量(int
通常是32位,有符号,两个补码,持有值-2 31 至2 31 -1)。
虽然在数学术语中你所做的转换是有道理的,但a
和b
的组合很多,表达式a*b
将超出{{1}所代表的范围}}。在C ++语言中,行为是未定义的,但假设您直接访问硬件,在当前处理器中它将环绕并生成有效范围内的数字,但不包含数学值int
。其余的操作将从错误的值开始并产生错误的结果。