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


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

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

#include<stdio.h> -H1"OJ2aF  
int main(){ .sd B3x  
    int a[2]={8,7};int min,i; >]Mq)V9  
    i=0,min=1; awj+#^  
    a[min]^=a^=a[min]^=a;//****变量 v}7@CP]nV  
//a=a^a[min],a[min]=a^a[min],a=a^a[min]; Bii6Z@kS  
    printf("%d %d ",a,a[min]); +(;8@"u  
gCv"9j<j  
}   PHQ{-b?4t  
这个代码输出是7,0 'RDWU7c9]  
****变量一行换成下一行的注释句运行结果是7,8; Ms.PO{wb  
但是这两个不是等价的么,书上说是等价的; G_V.H \w  
LQh^; ]^(  
#include<stdio.h> 7*zB*"B'1t  
int main(){ ~?FK ; (  
    int a,b; Dz[566UD  
    scanf("%d %d",&a,&b); +VSZhg,Np8  
    a^=b^=a^=b; 90Xt_$_}s  
    printf("%d %d",a,b); _ymJ~MK  
} ^Vag1 (hdq  
而这里面的****变量是成功的; LWD.  
为什么呢?
此帖悬赏中(剩余时间:已结束)...
最佳答案: 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生成的对应汇编代码: ]U_ec*a  
p'Bm8=AwD  
7 in a[1] in -8(%rbp) V|FrN*m  
6 /Y1 wu  
#8 in a[0] in -16(%rbp) I/uy>*  
movq    (%rax), %rax b?VV'{4  
movq    %rax, -8(%rbp) D> #l-{d  
movq    L_main.a(%rip), %rax 2<r\/-#pU  
movq    %rax, -16(%rbp) -5Utl os  
#i in -24(%rbp) ;min in -20(%rbp) 1>pe&n/  
movl    $0, -24(%rbp) p3]Q^KFS  
movl    $1, -20(%rbp) I.V:q!4*  
movslq  -24(%rbp), %rax K-Mc6  
movl    -16(%rbp,%rax,4), %ecx ;Yts\4BSM  
movslq  -20(%rbp), %rax WES#ZYtT  
movl    -16(%rbp,%rax,4), %edx uA~slS Z  
#a[min] in %ecx ;a in %edx K4 %/!`  
xorl    %ecx, %edx sC7/9</  
movl    %edx, -16(%rbp,%rax,4) vq'k|_Qi=  
#put it back in a[min] ?IhB-fd>@  
movslq  -24(%rbp), %rax 9F##F-%x  
#i=0 in %rax &|o$=Ad  
movl    -16(%rbp,%rax,4), %ecx d7Ro}>lp  
#a in %ecx ?6N3tk-2  
xorl    %edx, %ecx !a-b6Aa  
#xorl a with the result of a[min]^a ^v ni&sJ  
movl    %ecx, -16(%rbp,%rax,4) 4na8  
#put it back in a,now we put the original a[min] in a+i fi%r<]@  
movslq  -20(%rbp), %rax ?S[Y:<R{:  
#min=1 in %rax 8OFj0S1r`  
movl    -16(%rbp,%rax,4), %edx lK(Fg  
#a[min] in %edx,this a[min] differs from the origin, (-^bj  
#it is the result of the original a^a[min]  xvm5   
xorl    %ecx, %edx Gt-UJ-RR y  
#original a[min] in %ecx and the original a^a[min] in %edx P,z:Z| }8  
movl    %edx, -16(%rbp,%rax,4) >lzA ]aM$c  
#put it back in a[min],now we put the original a in a+min }*wLEa  
movslq  -24(%rbp), %rax ]\c,BWC@e  
movl    -16(%rbp,%rax,4), %esi Ngy=!g?Hk=  
movslq  -20(%rbp), %rax Jfhk@27T  
movl    -16(%rbp,%rax,4), %edx ~^U S/"  
#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 ,看看: Z=4{Vv*  
http://ideone.com/vmPSAw ;TcvA  
ODc9r }  
是否问题出在代码之外的错误,比如编译的和运行的不是同一个版本之类的问题?
级别: 北风资深评论员


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 r<Cr)%z!  
这句跟一句话里面使用多个自增一样,是未定义行为。简而言之就是,你在一句代码里面多次访问了a[min],并****出了修改。第二次的访问使用了修改前的值还是修改后的值,不同编译器的实现不一样。
级别: 北风资深评论员


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

我不知道那本书为什么这么说,但是我觉得大多数编译器都不是按照那本书来实现的。 J|U~W kW  
\NDW@!X  
a[min]^=a^=a[min]^=a; |wb_im  
等于 rr`_\ut  
/o$6"~t  
a[min]^=(a^=(a[min]^=a)); !p\ @1?  
等于 a0JMLLa [I  
3C=QWw?  
a[min] = a[min] ^ a  ; C<:wSS^@1  
a   = a   ^ a[min]; x%$6l  
a[min] = a[min] ^ a  ;