序列点 - Xor Swap on Array得到错误的结果

0 c++ compiler-construction

我学会了使用Xor运算符来交换两个整数,比如: 我最终得到a = 7和b = 21.
int a = 21;
int b = 7;
a^=b^=a^=b;

我试着像这样在数组上使用xor运算符:

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

    cout << a[0] <<',' <<a[1];
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是0.7
我在Xcode和g ++上编译代码,它们有同样的问题.

Xor swap on array在多行中运行良好:

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;
}
Run Code Online (Sandbox Code Playgroud)

我的输出为21,7

以下是我已经找到的信息:
- 问题是关于序列点:Array + XOR交换失败
- 即使对于简单的整数,它们也可能对这个未定义的行为产生副作用:为什么这个语句在java x ^ = y中不起作用^ = x ^ = y;
- 关于xor swap的一些其他问题:奇怪的XOR交换行为,同时将数据清零

所以我应该避免使用xor swap,相反,使用temp交换可以保证正确的结果.

但是我仍然不太清楚a[0]^=a[1]^=a[0]^=a[1];什么是序列点问题呢?

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


我的疑问是:
"如何编译器输出0,7a[0]^=a[1]^=a[0]^=a[1];."

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

但我不知道问题是什么a[0]^=a[1]^=a[0]^=a[1];,它看起来就像是一样a^=b^=a^=b;.所以我想知道它如何与数组一起工作.所以我会更多地了解类似"数组索引上的序列指针"

Alo*_*ave 7

如果没有插入序列点,则不能多次修改变量,如果这样做,则为未定义行为.

a^=b^=a^=b;
Run Code Online (Sandbox Code Playgroud)

尝试修改上述语句中的a和的值b会破坏此规则,最终会导致未定义的行为.
请注意,未定义的行为意味着任何行为都是可能的,您可以获得任何输出.

好读:

  • @DRVic:括号无济于事. (2认同)
  • @DRVic:不,不是C和C++.只有在序列点,您才能确定发生了哪些副作用,哪些副作用没有发生.请参见http://stackoverflow.com/q/4176328/395760 (2认同)