如何在预处理器中交换两个数字?

时间:2016-03-13 14:05:14

标签: c++

我尝试制作应该在参数中交换值的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 ++新手,任何人都可以告诉我为什么我不能这样做?

3 个答案:

答案 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)。

虽然在数学术语中你所做的转换是有道理的,但ab的组合很多,表达式a*b将超出{{1}所代表的范围}}。在C ++语言中,行为是未定义的,但假设您直接访问硬件,在当前处理器中它将环绕并生成有效范围内的数字,但不包含数学值int。其余的操作将从错误的值开始并产生错误的结果。