#define FUNC(x,y)x = ^ y; Y 1 X;在c

时间:2016-01-26 17:05:13

标签: c

当有定义然后是两个xor表达式时,我有成功的理解它意味着什么。这个定义的作用是什么?

我尝试发送x = 8,y = 7,结果是x = 15和y = 8 为什么它的幸福呢?

这是该计划:

#define FUNC(a,b) a^=b; b ^=a;

int main(){
    int x=8,y= 7;
    FUNC(x,y);
    printf("%d %d\n",x, y);
}

3 个答案:

答案 0 :(得分:5)

相同
int main(){
    int x=8,y= 7;
    x^=y; y ^=x;;
    printf("%d %d\n",x, y);
}

因为定义只是一个简单的文本替换,即所有a的地方都会被x取代,所有b的地方都会被y替换

^是一个有点明智的XOR运算符。

首先x = 8 ^ 7 = 15然后y = 7 ^ 15 = 8

这是因为当其中一个而不是两个都是1时,XOR会产生1

x =  8 = 0b00000000000000000000000000001000  // Assuming 32 bit int
y =  7 = 0b00000000000000000000000000000111  // Assuming 32 bit int
 x=x^y = 0b00000000000000000000000000001111 = 15

x = 15 = 0b00000000000000000000000000001111  // Assuming 32 bit int
y =  7 = 0b00000000000000000000000000000111  // Assuming 32 bit int
 y=y^x = 0b00000000000000000000000000001000 = 8
                                        ^^^
                                        Zero because both bits are 1

答案 1 :(得分:2)

更多原始问题:

这个宏有逐位方法的前两步来交换两个值:

(1) a ^= b
(2) b ^= a
(3) a ^= b

让我们稍微扩展一下:让x = a; y = b,我们将通过x和y的项来跟踪代数。首先,用其完整表达式替换每个“更新”:

(1) a = a ^ b
(2) b = b ^ a
(3) a = a ^ b

现在,替换x和y,从上到下滴答:

(1) a = x ^ y
(2) b = y ^ (x ^ y)
(3) a = (x ^ y) ^ (y ^ (x ^ y))

删除括号并重新排列术语:

(1) a = x ^ y
(2) b = x ^ y ^ y
(3) a = x ^ x ^ y ^ y ^ y

...留下我们的b = x; a = y

现在,由于您只有前两个步骤,因此您的最终结果是

b = x (original value of a)
a = x ^ y (a.k.a. a ^ b)

这能为您解释当前的问题吗?

答案 2 :(得分:1)

#define多语句宏的规范方法是

#define FUNC() do { statement1; statement2; } while(0)

这样即使if(b) FUNC();做了调用者的想法。

几年前进行了一次讨论,导致MISRA规则发生变化; MISRA不推荐"做"策略更长,因为他们说总是使用大括号,就像在if(b) { FUNC(); }中一样,可以优雅地处理不受保护的多语句宏(并防止像Apple证书那样的错误搞砸了) 。相反,do{...会掩盖使用大括号的失败。

我认为我个人仍然站在do方,只是因为我知道。

CERT recommends这项技术也是如此。