为什么i ^ = j ^ = i ^ = j不等于*i ^ =*j ^ =*i ^ =*j

klv*_*oek 4 javascript c pointers logical-operators

在C中,当有变量(假设两者都小于int)时,我们可以使用等式 ij

i^=j^=i^=j
Run Code Online (Sandbox Code Playgroud)

交换两个变量的值.例如,让int i = 3,j = 5; 经过计算i^=j^=i^=j,我有i = 5,j = 3.

但是,如果我使用两个int指针重新执行此操作*i^=*j^=*i^=*j,使用上面的示例,我将拥有i = 0j = 3.


在C.

1

    int i=3, j=5;
    i^=j^=i^=j; // after this i = 5, j=3
Run Code Online (Sandbox Code Playgroud)

2

    int i = 3, j= 5;
    int *pi = &i, *pj = &j;
    *pi^=*pj^=*pi^=*pj; // after this, $pi = 0, *pj = 5
Run Code Online (Sandbox Code Playgroud)

在JavaScript中

    var i=3, j=5;
    i^=j^=i^=j; // after this, i = 0, j= 3
Run Code Online (Sandbox Code Playgroud)

JavaScript中的结果使我对此更感兴趣

我的示例代码,在ubuntu服务器11.0和gcc上

    #include <stdio.h>
    int main(){
        int i=7, j=9;
        int *pi=&i, *pj=&j;
        i^=j^=i^=j;
        printf("i=%d j=%d\n", i, j);
        i=7, j=9;
        *pi^=*pj^=*pi^=*pj
        printf("i=%d j=%d\n", *pi, *pj);
    }
Run Code Online (Sandbox Code Playgroud)


c中的未定义行为

c中未定义的行为是导致这个问题的真正原因吗?

1

代码编译使用Visual Studio 2005在Windows 7上产生预期的结果(输出i = 7,j = 9两次.)

2

代码编译在ubuntu(gcc test.c)使用gcc产生意外结果(输出i = 7,j = 9然后i = 0,j = 9)

3

代码编译使用uccntu上的gcc(gcc -O test.c)产生预期的结果(输出i = 7,j = 9两次.)

oua*_*uah 8

i^=j^=i^=j 在C中是未定义的行为

您通过i在两个序列点之间修改两次来违反序列点规则.

这意味着实现可以自由分配任何值,甚至使程序崩溃.

出于同样的原因,*i^=*j^=*i^=*j也是未定义的行为.

(C99,6.5p2)"在前一个和下一个序列点之间,一个对象的存储值最多只能通过表达式的评估来修改一次."