在C语言中,当有变量(假设都是int
)i
小于j
时,我们可以用等式
i^=j^=i^=j
交换两个变量的值。例如,令int i = 3
,j = 5
;在计算 i^=j^=i^=j
之后,我有 i = 5
,j = 3
。
但是,如果我使用两个 int 指针重新执行此操作,使用 *i^=*j^=*i^=*j
,使用上面的示例,我将得到i = 0
和 j = 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/