Define a macro
swap(t, x, y)
that interchanges two arguments of typet
.(Block structure will help.)
The ideea is that a variable defined in a block structure exists only inside the block structure. So, I can create a temporary variable without affecting the code.
Here is my solution:
#include <stdio.h>
#define swap(t, x, y) {t tmp = x; x = y; y = tmp;}
int main() {
int x = 10, y = 2;
swap(int, x, y);
printf("%d %d", x, y);
return 0;
}
-
5\$\begingroup\$ I see that you have made a recent edit that invalidates some advice in the answers. It is often not recommended to make changes to your code once it has been reviewed (or even posted). Therefore, I have rolled back your edit so that all the answers can still be considered valid. \$\endgroup\$syb0rg– syb0rg2014年01月27日 18:19:11 +00:00Commented Jan 27, 2014 at 18:19
2 Answers 2
If you are using GCC, we can use the typeof()
(C99) keyword to get rid of one of the arguments. Also, add a do-while
so the macro to be used in contexts where it would otherwise be problematic.
#define SWAP(a, b) do { typeof(a) t; t = a; a = b; b = t; } while(0)
You could also use an exclusive-or (^=
) to get rid of that temporary variable, but that only works for integers.
#define SWAP(a, b) do { a ^= b; b ^= a; a ^= b; } while(0)
-
2\$\begingroup\$ But that doesn't support other arguments than ints (or other ordinal types), does it? \$\endgroup\$Simon Forsberg– Simon Forsberg2014年01月27日 17:37:18 +00:00Commented Jan 27, 2014 at 17:37
-
\$\begingroup\$ @SimonAndréForsberg You are correct. I have added in another solution that works with more types than just
int
s. \$\endgroup\$syb0rg– syb0rg2014年01月27日 17:49:40 +00:00Commented Jan 27, 2014 at 17:49 -
1\$\begingroup\$ Note that is you are using GCC 4.9, a somewhat better solution would be to use the
__auto_type
extension whose behaviour is similar to the C++11 keywordauto
. \$\endgroup\$Morwenn– Morwenn2014年03月26日 10:34:56 +00:00Commented Mar 26, 2014 at 10:34
First, macros should have ALL_CAPS
names to distinguish them from functions. Users need to be able to distinguish macros from functions because they behave slightly differently. For example, with your definition of swap()
as a macro, this code (for illustration purposes — not that it's good code) fails to compile:
if (swap(int, x, y), x) {
/* Do something */
}
Also, I'd put a defensive do { ... } while (0)
around your definition. Otherwise, this would cause an unexpected compilation error:
int main() {
int x = 10, y = 0;
if (x != 0)
SWAP(int, x, y);
else
x = 0;
printf("%d %d\n", x, y);
return 0;
}