在 C 中使用宏对 3 个值进行排序

Sort 3 values using macro in C

我尝试使用我在 SO 上找到的宏,但是,这段代码给出了一些错误:

#include <stdio.h>
#include <math.h>

#define SWAP(a,b) do {\
int tmp = a; \
   a = b; \
   b = tmp;} while(0)\

#define SORT(a,b,c) \
 if(a > b) { SWAP(a,b) } else if(a > c) { SWAP(a,c) } else if (b>c) { SWAP(b,c) }

int main()
{
    int a = 5, b = 2, c = 4;

    printf("a = %d, b = %d, c = %d\n", a, b, c);

    SORT(a,b,c);

    printf("a = %d, b = %d, c = %d\n", a, b, c);

    return 0;
}

但是,当我从 SWAP 宏中删除 do while 时,它起作用了,但给出的是 2,5,4 而不是 2,4,5

在 SWAP 宏中使用 do ... while 循环,我的代码出现错误:

Untitled2.c||In function ‘main’:|
Untitled2.c|10|error: expected ‘;’ before ‘}’ token|
Untitled2.c|18|note: in expansion of macro ‘SORT’|
Untitled2.c|10|error: expected ‘}’ before ‘else’|
Untitled2.c|18|note: in expansion of macro ‘SORT’|
Untitled2.c|10|error: expected ‘;’ before ‘}’ token|
Untitled2.c|18|note: in expansion of macro ‘SORT’|
Untitled2.c|10|error: expected ‘}’ before ‘else’|
Untitled2.c|18|note: in expansion of macro ‘SORT’|
Untitled2.c|10|error: expected ‘;’ before ‘}’ token|
Untitled2.c|18|note: in expansion of macro ‘SORT’|
Untitled2.c|23|error: expected declaration or statement at end of input|
||=== Build failed: 6 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

编辑:

修改了代码,但是结果不对,代码给我的是2,5,4而不是2,4,5

#include <stdio.h>
#include <math.h>

#define SWAP(a,b) do {\
int tmp = a; \
   a = b; \
   b = tmp;} while(0);

#define SORT(a,b,c) \
 if(a > b) { SWAP(a,b); } else if(a > c) { SWAP(a,c); } else if (b>c) { SWAP(b,c) }


int main()
{
    int a = 5, b = 2, c = 4;

    printf("a = %d, b = %d, c = %d\n", a, b, c);

    SORT(a,b,c);

    printf("a = %d, b = %d, c = %d\n", a, b, c);

    return 0;
}

您在第一个宏的末尾有一个额外的延续字符 \。你需要在 SWAP() 之后加分号,因为你有 while (0).

这样宏的行为就好像它们是函数一样

#define SWAP(a, b) \
    do {           \
        int d;     \
        d = a;     \
        a = b;     \
        b = d;     \
    } while (0)

#define SORT(a, b, c)      \
    do {                   \
        if (a > b)         \
            SWAP(a, b);    \
        else if (a > c)    \
            SWAP(a, c);    \
        else if (b > c)    \
            SWAP(b, c);    \
     } while (0)

do { ... } while (0)的目的是用分号结束一个multi-statement宏,当然在SWAP的情况下它也为临时变量[=16提供了作用域=].但是对于作用域,你可以只使用大括号 { ... } 但是在宏调用的末尾添加一个分号会创建一个空语句,因此 do { ... } while (0) 是解决这个问题的一个很好的技巧。

您需要用分号结束 while 循环:while(0);

您需要 semi-colon 来终止 do-while 循环。

   b = tmp;} while(0); 
                     ^ here

你的swap逻辑也不对。定义为:

 if(a > b) { SWAP(a,b) } if(b > c) { SWAP(b,c) } if (a>b) { SWAP(a,b) }

但是...

整个 marco 的事情相当混乱。您最好直接使用 if-else 语句或使用简单的 inline 函数。

宏是简单的文本替换,存在许多固有问题: - 它们不是类型安全的。 - 具有 side-effects 的宏参数会导致意外问题。考虑:

 #define SQR(x) ((x)*(x))

 SQR(x++); 

一般情况下,除非您真的别无选择,否则请避免使用宏。

您在 SORT 宏中 SWAP(a,c)SWAP(b,c) 之后缺少 ;

也在这里

#define SORT(a,b,c) \
     if(a > b) { SWAP(a,b) } else if(a > c) { SWAP(a,c) } else if (b>c) { SWAP(b,c) }

使用else是错误的。为了将三个值排序为 abc,它应该是

#define SORT(a,b,c) \
     {                          \
       if((a) > (b)) { SWAP(a,b); } \
       if((a) > (c)) { SWAP(a,c); } \
       if((b) > (c)) { SWAP(b,c); } \
     }

编辑

abc 添加了 ( ),因为它们可能表示复杂的表达式。

让我们检查一下您的排序宏:

a=5, b=2, c=4

if(a > b) {
   SWAP(a,b)
} else if(a > c) {
   SWAP(a,c)
} else if (b>c) {
   SWAP(b,c)
} 

a 大于 b -> 它们将被交换。
a=2, b=5, c=4
其余为 else。所以它不会做任何其他事情

第9行,添加调用sort时的宏,执行if条件后循环终止,后面用else。 所以这就是你应该使用所有条件的要点。 更好的建议是使用递归方法进行排序:)