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


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

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

#include<stdio.h> CM~)\prks  
int main(){ Pirc49c  
    int a[2]={8,7};int min,i; F7L+bv   
    i=0,min=1; CFn!P;.!  
    a[min]^=a^=a[min]^=a;//****变量 h PH= .rX  
//a=a^a[min],a[min]=a^a[min],a=a^a[min]; Q7f\ 5QjT  
    printf("%d %d ",a,a[min]); }}K4 4<]u  
Uln[UK  
}   8g&uCv/Uk  
这个代码输出是7,0 \u2p]K>  
****变量一行换成下一行的注释句运行结果是7,8; %?R}sUo  
但是这两个不是等价的么,书上说是等价的; @/XA*9]l  
EubF`w$KWX  
#include<stdio.h> L)J0T Sh  
int main(){ !{"{(h)+@  
    int a,b; WHMt$W}%  
    scanf("%d %d",&a,&b); )"wWV{k  
    a^=b^=a^=b; jBarYg  
    printf("%d %d",a,b); 0vt?yD  
} @9-z8PyF  
而这里面的****变量是成功的; Y6 &w0~?!  
为什么呢?
此帖悬赏中(剩余时间:已结束)...
最佳答案: 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生成的对应汇编代码: 86%weU/*  
vp  mSzh  
7 in a[1] in -8(%rbp) ^D4b\mF  
T>f-b3dk  
#8 in a[0] in -16(%rbp) iT^lk'?{O  
movq    (%rax), %rax njUM>E,'  
movq    %rax, -8(%rbp) Kyl(  
movq    L_main.a(%rip), %rax =:"@YD^a4  
movq    %rax, -16(%rbp) %< j=&  
#i in -24(%rbp) ;min in -20(%rbp) H50nR$$<*Y  
movl    $0, -24(%rbp) *c3 o&-ke9  
movl    $1, -20(%rbp) r1?LKoJOn  
movslq  -24(%rbp), %rax z0Zl'  
movl    -16(%rbp,%rax,4), %ecx 0e7v ?UT  
movslq  -20(%rbp), %rax }+=@Ci  
movl    -16(%rbp,%rax,4), %edx JK_$A;Q  
#a[min] in %ecx ;a in %edx @~N#)L^  
xorl    %ecx, %edx O/-OW: 03  
movl    %edx, -16(%rbp,%rax,4) Ppp&3h[dW)  
#put it back in a[min] F H%yyT  
movslq  -24(%rbp), %rax >C&!# 3  
#i=0 in %rax 6R,;c7Izhd  
movl    -16(%rbp,%rax,4), %ecx { U<h tl4  
#a in %ecx D@ lJ^ +  
xorl    %edx, %ecx p_nrua?  
#xorl a with the result of a[min]^a 23fAc"@ B  
movl    %ecx, -16(%rbp,%rax,4) vaU7tJ:  
#put it back in a,now we put the original a[min] in a+i |JDJ{;o  
movslq  -20(%rbp), %rax W>Kwl*Cis"  
#min=1 in %rax @]7\.>)  
movl    -16(%rbp,%rax,4), %edx JjCf<ktE.  
#a[min] in %edx,this a[min] differs from the origin, 0qZ)$ YKq  
#it is the result of the original a^a[min] -Tt}M#W   
xorl    %ecx, %edx j AE0$u~.  
#original a[min] in %ecx and the original a^a[min] in %edx -jy"?]ve.  
movl    %edx, -16(%rbp,%rax,4) !RD,:\5V  
#put it back in a[min],now we put the original a in a+min 4ca-!pI0  
movslq  -24(%rbp), %rax /%c^ i!=f"  
movl    -16(%rbp,%rax,4), %esi 1L|(:m+  
movslq  -20(%rbp), %rax xRUYJ=|oh  
movl    -16(%rbp,%rax,4), %edx 8G P}g?%  
#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 ,看看: Bk?8 zYp  
http://ideone.com/vmPSAw V ]79 vC  
96(R'^kNX  
是否问题出在代码之外的错误,比如编译的和运行的不是同一个版本之类的问题?
级别: 北风资深评论员


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


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

我不知道那本书为什么这么说,但是我觉得大多数编译器都不是按照那本书来实现的。 *2Kte'+q  
/);6 j,x  
a[min]^=a^=a[min]^=a; UlR7_   
等于 !+U.)u9 '  
L;;x%>  
a[min]^=(a^=(a[min]^=a)); '=xl}v  
等于 H.e@w3+h  
TzjZGs W[V  
a[min] = a[min] ^ a  ; Vj1AW<  
a   = a   ^ a[min]; AkF3F^  
a[min] = a[min] ^ a  ;