简体   繁体   中英

How to swap two numbers in preprocessor?

I try to make makro which should swap values in parameters. My code:

#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;
}

I'm new in C++ and can anyone tell me why can't I make it like that?

You can't do it because when the macro is expanded the "arguments" are replaced as is . So your macro when expanded will look like

2 = 2 * 4;
4 = 2 / 4;
2 = 2 / 4;

In other words, you try to assign values to a value, which makes no sense.

One solution is to use variables instead, but the one I recommend is to avoid using preprocessor macros for this to begin with, and instead create an inline function which does this "properly". Or, you know, just use std::swap .

Oh and another thing: You say you want to "swap two numbers in preprocessor". That's impossible. The preprocessor doesn't do anyhing, it just replaces the macro invocation with the body of the macro, to create code that the compiler sees and compiles into executable code, so the calculation you do is done at run-time anyway. If you want to do something at compile-time (but not by the preprocessor) then you should look into templates and constexpr .

std::swap does what you want.

If your task really is to write a macro for that, write one which uses that function. But be prepared that your teacher might not like this solution.

#define swap(x, y) std::swap(x, y)

If you want to avoid using std::swap , you can also assign the tuple (x, y) to (y, x) :

#define swap(x, y) std::tie(y, x) = std::make_tuple(x, y)

I am not sure what the question is, but you should consider that computers in general don't work on proper mathematical concepts, but something much more restricted. When you use an int , it is not an integer , but a variable that holds a value in some restricted range ( int is often 32bit, signed, two's complement, holding values -2 31 to 2 31 -1).

While in mathematical terms the transformation you did makes sense, there are many combinations of a and b for which the expression a*b will fall out of the range representable by int . The behavior is undefined in the C++ language, but assuming you were accessing the hardware directly, in current processors it will wrap around and produce a number within the valid range, yet one that does not hold the mathematical value a*b . The rest of the operations will be starting from the wrong value and yield wrong results.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM