简体   繁体   English

#定义FUNC(x,y)x = ^ y; y ^ x; 在C

[英]#define FUNC(x,y) x=^y; y^x; in c

Im having trubles to understand what it means when there is define and then two xor expressions. 我有麻烦去理解当有定义然后有两个异或表达式时的含义。 what this define does? 这个定义做什么?

i try to send x=8, y=7 and the result was that x=15 and y=8 why its happand? 我尝试发送x = 8,y = 7,结果是x = 15和y = 8,为什么会发短信?

this is the program: 这是程序:

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

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

It is just the same as 就是一样的

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

because the define will just be a simple text substitution, ie all places with a will be replaced by x and all places with b will be replaced with y . 因为定义只是一个简单的文本替换,即所有带有a将被x替换,所有带有b将被y替换。

The ^ is a bit wise XOR operator. ^是按位XOR运算符。

So first x = 8 ^ 7 = 15 then y = 7 ^ 15 = 8 所以首先x = 8 ^ 7 = 15然后y = 7 ^ 15 = 8

This is because XOR produce 1 when one of the bits but not both are 1 这是因为XOR产生1时位中的一个而不是两个都是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

More to the original question: 更多关于原始问题的信息:

This macro has the first two steps of the bit-wise method to exchange two values: 该宏具有按位方法的前两个步骤,可以交换两个值:

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

Let's expand this a little: let x = a; 让我们稍微扩展一下:让x = a; y = b, and we'll trace the algebra through terms of x and y. y = b,我们将通过x和y追踪代数。 First, replace each "update" with its full expression: 首先,用完整的表达式替换每个“更新”:

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

Now, substitute x and y, trickling down from top to bottom: 现在,将x和y替换为从上到下滴下:

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

Drop the parentheses and rearrange terms: 删除括号并重新排列术语:

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

... leaving us with b = x; ...给我们留下b = x; a = y a = y

Now, since you have only the first two steps, your final result is 现在,由于只有前两个步骤,因此最终结果是

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

Does that explain the immediate problem for you? 这为您解释了眼前的问题吗?

The canonical way to #define multi-statement macros is 定义多语句宏的规范方法是

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

That way even if(b) FUNC(); 即使if(b) FUNC(); does what the caller thinks. 做到了来电者的想法。

There has been a discussion a few years ago which led to a change in the MISRA rules concerning this; 几年前进行了讨论,导致MISRA对此进行了更改。 MISRA does not recommend the "do" strategy any longer, because they say one should always use curly braces, as in if(b) { FUNC(); } MISRA不再推荐“做”策略,因为他们说应该总是使用花括号,例如if(b) { FUNC(); } if(b) { FUNC(); } which would handle unprotected multi-statement macros gracefully (and prevent bugs like the Apple certificate goto screw-up). if(b) { FUNC(); }可以很好地处理不受保护的多语句宏(并防止Apple证书goto搞砸之类的错误)。 Instead, a do{... would camouflage the failure to use braces. 相反, do{...会伪装使用花括号的失败。

I think I personally still side on the do side, if only because I know it. 我想我个人还是站在do一方,即使仅仅是因为我知道这一点。

CERT recommends the technique as well. CERT也推荐该技术。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM