上一主题下一主题
关键字
主题 : 异或交换两个变量值的疑惑
级别: 北风技术菜鸟


UID: 478714
精华: 0
发帖: 1448
威望: 5132 点
学点: 3374 点
贡献: 171 点
好评: 0 点
学币: 16 个
注册时间: 2014-07-23
最后登录: 2015-04-02
楼主  发表于: 2015-02-09 01:21||

异或交换两个变量值的疑惑

#include<stdio.h> S9-K  
int main(){  t\u0\l>  
    int a[2]={8,7};int min,i; Rq9v+Xq2  
    i=0,min=1; +7d%)t  
    a[min]^=a^=a[min]^=a;//****变量 ~Ui<y=d  
//a=a^a[min],a[min]=a^a[min],a=a^a[min]; VO[s:e9L  
    printf("%d %d ",a,a[min]); MQw{^6Z>1  
SJj0*ry:  
}   OB l-6W  
这个代码输出是7,0 $w#C;2k]N  
****变量一行换成下一行的注释句运行结果是7,8; q_ ']i6  
但是这两个不是等价的么,书上说是等价的; %/-Z1Nv*#  
Y(W>([59  
#include<stdio.h> uF L~^vz  
int main(){ >jRz4%  
    int a,b; \0'o*nlJ  
    scanf("%d %d",&a,&b); vw>O;u.]B  
    a^=b^=a^=b; cAV9.VS<L  
    printf("%d %d",a,b); srO {Ci0  
} h 5t,5e}  
而这里面的****变量是成功的; fp|b@  
为什么呢?
此帖悬赏中(剩余时间:已结束)...
最佳答案: 2 学点
热心助人剩余点数: 1 学点
级别: 北风资深评论员


UID: 478710
精华: 0
发帖: 4520
威望: 6415 点
学点: 7638 点
贡献: 199 点
好评: 0 点
学币: 119 个
注册时间: 2014-07-23
最后登录: 2015-04-06
沙发(1楼)  发表于: 2015-02-09 01:27||

gcc 4.2.1下 gcc -S生成的对应汇编代码: Ufw_GYxan  
-q&K9ZCl `  
7 in a[1] in -8(%rbp) $%:=;1Jl  
Qk5pRoL_  
#8 in a[0] in -16(%rbp) FGRdA^`  
movq    (%rax), %rax 4DwQ7KX  
movq    %rax, -8(%rbp) i #pBzJ  
movq    L_main.a(%rip), %rax ;xXD2{q  
movq    %rax, -16(%rbp) (=\))t8J  
#i in -24(%rbp) ;min in -20(%rbp) `<#Ufi*c  
movl    $0, -24(%rbp) ByU&fx2Z  
movl    $1, -20(%rbp) JLz.lk*.  
movslq  -24(%rbp), %rax 6&,{"N0 T  
movl    -16(%rbp,%rax,4), %ecx ##QKXSD  
movslq  -20(%rbp), %rax IE*5p6IM~  
movl    -16(%rbp,%rax,4), %edx a#pM9n~a  
#a[min] in %ecx ;a in %edx 8 *Y(wqH  
xorl    %ecx, %edx #TG7WF 5  
movl    %edx, -16(%rbp,%rax,4) dxa[9>V  
#put it back in a[min] s$3WJ'yr  
movslq  -24(%rbp), %rax b/]@G05>>  
#i=0 in %rax xXQW|#X\  
movl    -16(%rbp,%rax,4), %ecx Rq[VP#  
#a in %ecx |h  3`z  
xorl    %edx, %ecx m`!Vryf  
#xorl a with the result of a[min]^a 1,Uf-i  
movl    %ecx, -16(%rbp,%rax,4) NGp^/PZX0  
#put it back in a,now we put the original a[min] in a+i 0ZJN<AzbA  
movslq  -20(%rbp), %rax N 6t`45  
#min=1 in %rax eFz!`a^dX  
movl    -16(%rbp,%rax,4), %edx  KrqO7  
#a[min] in %edx,this a[min] differs from the origin, & m~   
#it is the result of the original a^a[min] KKGwMJku}  
xorl    %ecx, %edx FX&)~)  
#original a[min] in %ecx and the original a^a[min] in %edx hB1Gtc4n  
movl    %edx, -16(%rbp,%rax,4) 'U{6LSaCb  
#put it back in a[min],now we put the original a in a+min IEQ6J}L  
movslq  -24(%rbp), %rax v>' mW  
movl    -16(%rbp,%rax,4), %esi /e50&]2w  
movslq  -20(%rbp), %rax I%# e\  
movl    -16(%rbp,%rax,4), %edx QMBV"E_aY  
#pass the parameters by registers,a+i in %esi,a+min in %edx
级别: 北风资深评论员


UID: 478710
精华: 0
发帖: 4520
威望: 6415 点
学点: 7638 点
贡献: 199 点
好评: 0 点
学币: 119 个
注册时间: 2014-07-23
最后登录: 2015-04-06
板凳(2楼)  发表于: 2015-02-09 01:27||

代码没问题,输出确实是7 8 ,看看: YW}/C wB  
http://ideone.com/vmPSAw g/@CESfm'  
dG rA18  
是否问题出在代码之外的错误,比如编译的和运行的不是同一个版本之类的问题?
级别: 北风资深评论员


UID: 478710
精华: 0
发帖: 4520
威望: 6415 点
学点: 7638 点
贡献: 199 点
好评: 0 点
学币: 119 个
注册时间: 2014-07-23
最后登录: 2015-04-06
地板(3楼)  发表于: 2015-02-09 01:27||

a[min]^=a^=a[min]^=a G'0]m-)dw  
这句跟一句话里面使用多个自增一样,是未定义行为。简而言之就是,你在一句代码里面多次访问了a[min],并****出了修改。第二次的访问使用了修改前的值还是修改后的值,不同编译器的实现不一样。
级别: 北风资深评论员


UID: 478710
精华: 0
发帖: 4520
威望: 6415 点
学点: 7638 点
贡献: 199 点
好评: 0 点
学币: 119 个
注册时间: 2014-07-23
最后登录: 2015-04-06
地下室(4楼)  发表于: 2015-02-09 01:27||

我不知道那本书为什么这么说,但是我觉得大多数编译器都不是按照那本书来实现的。 v_ U$jjO1  
ef Moi'v  
a[min]^=a^=a[min]^=a; Az`c? W%  
等于 RZ6[+Ygn  
MJzY|  
a[min]^=(a^=(a[min]^=a)); mB.j?@Y%  
等于 'o!{YLJ fM  
-J06H&/k  
a[min] = a[min] ^ a  ; xpO'.xEs  
a   = a   ^ a[min]; YV{^2)^  
a[min] = a[min] ^ a  ;