9
\$\begingroup\$

Define a macro swap(t, x, y) that interchanges two arguments of type t.(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;
}
\$\endgroup\$
  • 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 Jan 27 '14 at 18:19
12
\$\begingroup\$

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)
\$\endgroup\$
  • 2
    \$\begingroup\$ But that doesn't support other arguments than ints (or other ordinal types), does it? \$\endgroup\$ – Simon Forsberg Jan 27 '14 at 17:37
  • \$\begingroup\$ @SimonAndréForsberg You are correct. I have added in another solution that works with more types than just ints. \$\endgroup\$ – syb0rg Jan 27 '14 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 keyword auto. \$\endgroup\$ – Morwenn Mar 26 '14 at 10:34
10
\$\begingroup\$

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;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.