序列点 - Xor交换数组得到错误的结果 [英] Sequence Point - Xor Swap on Array get wrong result

查看:101
本文介绍了序列点 - Xor交换数组得到错误的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我学习使用Xor运算符交换两个整数,例如:

int a = 21;

int b = 7;

a ^ = b ^ = a ^ = b;


我终于得到a = 7和b = 21。



我尝试使用xor操作符在数组上像这样:

  int main()
{
int a [] = { 7,21};
a [0] ^ = a [1] ^ = a [0] ^ = a [1];

cout<< a [0]<<','<< a [1]
return 0;
}

输出为 0,7
我在Xcode和g ++上编译代码,他们有同样的问题。



Xor交换数组工作正常,多行:

  int main()
{
int a [] = {7,21};
a [0] ^ = a [1];
a [1] ^ = a [0];
a [0] ^ = a [1];
cout<< a [0]<<','<< a [1]
return 0;
}

我会输出 21,7 / p>

这是我已经找到的信息:

- 问题是关于序列点:数组+ XOR交换失败

- 即使对于简单整数,它们可能对此未定义行为有副作用:为什么这个语句在java中不起作用x ^ = y ^ = x ^ = y;

- 有关xor交换的一些其他问题:清零数据时的异常XOR交换行为



所以我应该避免使用xor交换,保证正确的结果。



但我还是不太清楚在上发生了什么a [0] ^ = a [1] ^ = a [0 ] ^ = a [1]; 它的序列点问题是什么?



我无法弄清楚编译器有什么不同 a [0] ^ = a [1] ^ = a [0] ^ = a [1]; a ^ = b ^ = a ^ = b;






我的疑问是

编译器输出 0,7 for a [0] ^ = a [1] ^ = a [0] ^ = a [1];



我知道这是序列指针问题,我可以理解为什么 printf d,%d,i ++,i ++); 未定义为函数的一些编译器解析参数从左到右,有些从右到左。



但我不知道 a [0] ^ = a [1] ^ = a [0] ^ = a [1]; ,它看起来与 a ^ = b ^ = a ^ = b; 相同。所以我想知道它如何与数组一起使用。

解决方案

You不能修改变量多于一次而没有中间序列点,如果这样做,则是未定义行为

 <$ c ^ c> a ^ = b ^ = a ^ = b; 

尝试修改 a 上面的语句中的 b 打破了这个规则,你最终会得到一个未定义的行为。

注意,未定义的行为意味着任何行为都是可能的,获得任何输出。



良好阅读:




I learned using Xor operator to swap two integers,like:
int a = 21;
int b = 7;
a^=b^=a^=b;

I would finally get a=7 and b=21.

I try to use xor operator on array like this way:

int main()
{
    int a[] = {7,21};  
    a[0]^=a[1]^=a[0]^=a[1];

    cout << a[0] <<',' <<a[1];
    return 0;
}

The output is 0,7
I compile the code on Xcode and g++, they have the same issue.

Xor swap on array works fine with multiple lines:

int main()
{
    int a[] = {7,21};  
    a[0]^=a[1];
    a[1]^=a[0];
    a[0]^=a[1];
    cout << a[0] <<',' <<a[1];
    return 0;
}

I would get output as 21,7

Here is the information what I already find:
- the issue is about sequence point: Array + XOR swap fails
- even for simple integers, they may have side affect to this undefined behavior: Why is this statement not working in java x ^= y ^= x ^= y;
- some other issue on xor swap: Weird XOR swap behavior while zeroing out data

So I should avoid using xor swap, instead, swap with temp would guarantee correct result.

But I still not very clear about what happen on a[0]^=a[1]^=a[0]^=a[1]; what is the sequence point issue with it?

I could not figure out what's the different on compiler between a[0]^=a[1]^=a[0]^=a[1]; and a^=b^=a^=b; ?


My doubt is:
" How does compiler output 0,7 for a[0]^=a[1]^=a[0]^=a[1];. "

I know this is sequence pointer issue, I could understand why printf("%d,%d",i++, i++); is undefined as some compiler parse parameter of function from left to right, and some do it from right to left.

But I do not know what is the problem on a[0]^=a[1]^=a[0]^=a[1];, it looks just the same as a^=b^=a^=b;. So I'd like to know how it works with array. So that I would know more about kind like "sequence pointer on index of array"

解决方案

You cannot modify a variable more than once without an intervening sequence point, if you do so, it is Undefined Behavior.

a^=b^=a^=b;

Trying to modify the values of a and b in the above statement breaks this rule and you end up with an Undefined Behavior.
Note that Undefined Behavior means that any behavior is possible and you can get any output.

Good Reads:

这篇关于序列点 - Xor交换数组得到错误的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆