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

标签 javascript c pointers logical-operators

在C语言中,当有变量(假设都是int)i小于j时,我们可以用等式

i^=j^=i^=j

交换两个变量的值。例如,令int i = 3j = 5;在计算 i^=j^=i^=j 之后,我有 i = 5j = 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

2

    int i = 3, j= 5;
    int *pi = &i, *pj = &j;
    *pi^=*pj^=*pi^=*pj; // after this, $pi = 0, *pj = 5

在 JavaScript 中

    var i=3, j=5;
    i^=j^=i^=j; // after this, i = 0, j= 3

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);
    }


c 中的未定义行为

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

1

代码编译使用 windows 7 上的 visual studio 2005 产生预期结果(输出 i = 7,j = 9 两次。)

2

在 ubuntu 上使用 gcc 编译的代码 ( gcc test.c ) 产生了意想不到的结果 ( Output i = 7, j = 9 then我 = 0, j = 9 )

3

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

最佳答案

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

在两个序列点之间修改 i 两次违反了序列点规则。

这意味着实现可以自由分配任何值,甚至可以让您的程序崩溃。

同理,*i^=*j^=*i^=*j也是未定义行为。

(C99, 6.5p2) "Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression."

关于javascript - 为什么 i^=j^=i^=j 不等于 *i^=*j^=*i^=*j,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12331518/

相关文章:

javascript - 如何在每次测试前重置 Jest 模拟函数调用计数

javascript - 基于Jquery中的下拉选择框填充输入文本框

javascript - 如何在网格布局中跳过行中的列

将 C 结构转换为 unsigned char

javascript - d3.csvParse无法正确读取字符串

python - 在C中访问python结构数组

c - 如何使用函数指针访问多个文件中的函数

指针取消引用符号 * 可以称为 "many"吗?

c - 对三重指针的作用极度困惑

c - Yacc, union 结构指针