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?
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
.
The ^
is a bit wise XOR operator.
So first x = 8 ^ 7 = 15
then y = 7 ^ 15 = 8
This is because XOR produce 1
when one of the bits are 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; y = b, and we'll trace the algebra through terms of x and 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:
(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; 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();
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 does not recommend the "do" strategy any longer, because they say one should always use curly braces, as in if(b) { FUNC(); }
if(b) { FUNC(); }
which would handle unprotected multi-statement macros gracefully (and prevent bugs like the Apple certificate goto screw-up). Instead, a do{...
would camouflage the failure to use braces.
I think I personally still side on the do
side, if only because I know it.
CERT recommends the technique as well.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.