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


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

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

#include<stdio.h> @.gCeMlOf  
int main(){ Kzmgy14o  
    int a[2]={8,7};int min,i; HY 42G#^  
    i=0,min=1; <6`,)(dj  
    a[min]^=a^=a[min]^=a;//****变量 'z\F-Ttq  
//a=a^a[min],a[min]=a^a[min],a=a^a[min]; B O"+m  
    printf("%d %d ",a,a[min]); !P ;qc  
K}zw%!ex  
}   k{;:KW|  
这个代码输出是7,0 G cbal:q  
****变量一行换成下一行的注释句运行结果是7,8; FX'W%_f,  
但是这两个不是等价的么,书上说是等价的; ~C[,P\,  
'R$~U?i8  
#include<stdio.h> ~7k b4[  
int main(){ j@:L MR>  
    int a,b; }%}eyLm(  
    scanf("%d %d",&a,&b); o 1b#q/  
    a^=b^=a^=b; 3)7'dM  
    printf("%d %d",a,b); BU)4g[4  
} (O&b:D/Y  
而这里面的****变量是成功的; /q^( uWu  
为什么呢?
此帖悬赏中(剩余时间:已结束)...
最佳答案: 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生成的对应汇编代码: LwlO)|E  
8TBv~Q u  
7 in a[1] in -8(%rbp) vX@T Zet0  
`5Bv2 wlIV  
#8 in a[0] in -16(%rbp) &HQ_e$1  
movq    (%rax), %rax T095]*Hm  
movq    %rax, -8(%rbp) G! Y l0Zr  
movq    L_main.a(%rip), %rax bN\;m^xfu  
movq    %rax, -16(%rbp) W:maE9E=  
#i in -24(%rbp) ;min in -20(%rbp) Z;O!KsJ  
movl    $0, -24(%rbp) x2,;ar\D  
movl    $1, -20(%rbp) qRSoF04!R  
movslq  -24(%rbp), %rax XJ!?>)N .  
movl    -16(%rbp,%rax,4), %ecx wz..  
movslq  -20(%rbp), %rax enx+,[  
movl    -16(%rbp,%rax,4), %edx GbC@ |  
#a[min] in %ecx ;a in %edx h`dHk]O  
xorl    %ecx, %edx /X]gm\x7s  
movl    %edx, -16(%rbp,%rax,4) CNe(]HIOH  
#put it back in a[min] GorEHlvVh  
movslq  -24(%rbp), %rax H_ a##z  
#i=0 in %rax Yy~xNj5OS  
movl    -16(%rbp,%rax,4), %ecx We++DWp  
#a in %ecx .i {yW  
xorl    %edx, %ecx 8BrC@L2E0  
#xorl a with the result of a[min]^a R$ !]z(  
movl    %ecx, -16(%rbp,%rax,4) %+ nM4)h  
#put it back in a,now we put the original a[min] in a+i kbL7Xjk  
movslq  -20(%rbp), %rax =0L%<@yA  
#min=1 in %rax ]- 6q`'?[  
movl    -16(%rbp,%rax,4), %edx S\]9mHJI  
#a[min] in %edx,this a[min] differs from the origin, ZbiC=uh  
#it is the result of the original a^a[min] # > I_  
xorl    %ecx, %edx S|xwYaoy%  
#original a[min] in %ecx and the original a^a[min] in %edx y4! :l =E^  
movl    %edx, -16(%rbp,%rax,4) Yecdw'BW?  
#put it back in a[min],now we put the original a in a+min Ml9m# c  
movslq  -24(%rbp), %rax bo/<3gR  
movl    -16(%rbp,%rax,4), %esi amq, ^  
movslq  -20(%rbp), %rax _xH<R  
movl    -16(%rbp,%rax,4), %edx 7NT0]j(w-  
#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 ,看看: J[Mj8ee#  
http://ideone.com/vmPSAw svxjad@l/  
SKNHLE}  
是否问题出在代码之外的错误,比如编译的和运行的不是同一个版本之类的问题?
级别: 北风资深评论员


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


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

我不知道那本书为什么这么说,但是我觉得大多数编译器都不是按照那本书来实现的。 U;]h/3P  
qc/)l~]?g{  
a[min]^=a^=a[min]^=a; RAoY`AWI  
等于 ^Zq3K  
xtd1>|  
a[min]^=(a^=(a[min]^=a)); q!) nSD  
等于 )#Id=c  
_lZWy$rm%  
a[min] = a[min] ^ a  ; p~<d8n4UH  
a   = a   ^ a[min]; TxmKmZ u  
a[min] = a[min] ^ a  ;