当有定义然后是两个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);
}
答案 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这项技术也是如此。