通过宏观函数的循环置换

时间:2015-01-18 00:06:28

标签: c macros

在C中,我想创建一个宏函数,将第一个参数的内容放入第二个,第二个的内容放入第三个,第三个的内容放入第一个。下面的代码没有宏:

void circ2 ( int *a, int *b, int *c ){
    int temp1;
    int temp2;
    int temp3;
    temp1 = *a;
    temp2 = *b;
    temp3 = *c; 
    *a = temp3;
    *b = temp1;
    *c = temp2;
    //printf( "%d\n%d\n%d\n", a, b, c );
}

int main(){
    int x;
    int y;
    int z;
    x = 1;
    y = 2;
    z = 3;

    //circ(a, b, c);
    circ(x, y, z);
    printf( "%d\n%d\n%d\n", x, y, z );
    return 0;
}

我尝试创建的宏功能:

#define temporary
#define temporary2
#define temporary3
#define circ(x, y, z) (x != y && x != z && y != z) ? temporary = x, temporary2 = y, temporary3 = z, y = temporary, z = temporary2, x = temporary3 : x, y, z

但是我收到以下错误:

  

错误:'='标记之前的预期表达式

我在哪里犯了错误?

4 个答案:

答案 0 :(得分:3)

temporarytemporary2temporary3已定义,但您尚未提供他们应该扩展到的值,因此宏的结果扩展看起来像

(x != y && x != z && y != z) ? = x, = y, = z(等等)

如果您知道宏参数的类型为int,则可以将宏扩展为代码块,如下所示:

#include <stdio.h>

#define circ(x,y,z) {int tmp=z; z=y; y=x; x=tmp; }

int main()
{
   int a=1, b=2, c=3;
   circ(a,b,c);
   printf("a=%d, b=%d, c=%d\n",a,b,c);
}

输出:

a = 3,b = 1,c = 2

答案 1 :(得分:3)

非宏代码中的一个小错误:circ()的参数需要是指针。 (我试图编辑,但是它在6个字符的限制之内。)调用应该是:

    circ(&x, &y, &z); 

排列需要是可执行代码,但需要条件执行。尝试类似:

#define circ3(x, y, z) {int circ3__temp__=x; x = y; y = z; z = circ3__temp___;}

这将生成代码以置换三个int值,并在支撑块内部使用局部变量。代码是内联生成的,临时变量的奇数名称是尝试不复制调用范围中使用的任何名称。

请注意,当与iffor等一起使用控制表达式语句时,这不会像表达式那样。例如

if (condition)
    circ3(a,b,c); /* semicolon here causes problem */
else /* "else without if" error here is that problem */
    circ3(x,y,z);

因此,对于void函数调用来说,它不是一个完美的插件。你需要删除;在通话中,或在宏调用周围添加{}括号。

答案 2 :(得分:2)

我怀疑问题在于temporarytemporary2等未申报。您可能希望使宏跨越多个语句,以分号分隔,而不是使用逗号运算符。

答案 3 :(得分:2)

当你写:

#define temporary

您要对C预处理器说“临时”已定义,并且必须替换为空。 所以当你写:

#define circ(x,y,z) (x != y && x != z && y != z) ? temporary = x, temporary2 = y, temporary3 = z, y = temporary, z = temporary2, x = temporary3 : x, y, z
circ(a,b,c)

预处理器将替换circ(a,b,c):

(a != b && a != c && b != c) ?  = x, = y, = z, y = , z = , x = : x, y, z

并且C编译器不理解它。

希望这会有所帮助:

#define circ(x, y, z) do{int w;w=z;z=y;y=x;x=w;}while(0)