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


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

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

#include<stdio.h> &,KxtlR![  
int main(){ R@"N{ [9  
    int a[2]={8,7};int min,i; !$_mWz  
    i=0,min=1; O`@$YXuD  
    a[min]^=a^=a[min]^=a;//****变量 aD 3$z;E  
//a=a^a[min],a[min]=a^a[min],a=a^a[min]; . X:{s,@  
    printf("%d %d ",a,a[min]); (& ~`!]  
);,#H`'  
}   gHox{*hb[  
这个代码输出是7,0 ef,6>xv  
****变量一行换成下一行的注释句运行结果是7,8; f_z2d+  
但是这两个不是等价的么,书上说是等价的; 3QXGbu}:h!  
co~TQpy^  
#include<stdio.h> z Gz5|u  
int main(){ 4|XE f,  
    int a,b; A:p0p^*  
    scanf("%d %d",&a,&b); "`&?<82  
    a^=b^=a^=b; e?f[t*td  
    printf("%d %d",a,b); ;9prsvf  
} ~xHr/:  
而这里面的****变量是成功的; hW|t~|j#_  
为什么呢?
此帖悬赏中(剩余时间:已结束)...
最佳答案: 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生成的对应汇编代码: fX^ <H_1$G  
"**Tw'  
7 in a[1] in -8(%rbp) o'+p,_y9Y@  
Na=.LW-ma=  
#8 in a[0] in -16(%rbp) +" |?P  
movq    (%rax), %rax CC"}aV5  
movq    %rax, -8(%rbp) +-"uJIwMD  
movq    L_main.a(%rip), %rax  0@ 7%  
movq    %rax, -16(%rbp) (#KSwWo{ed  
#i in -24(%rbp) ;min in -20(%rbp) ( y0  
movl    $0, -24(%rbp) &6deds  
movl    $1, -20(%rbp) icS% ])3LF  
movslq  -24(%rbp), %rax uW;[FTcqy$  
movl    -16(%rbp,%rax,4), %ecx N(c`h  
movslq  -20(%rbp), %rax = j)5kY`  
movl    -16(%rbp,%rax,4), %edx u]0{#wu;g  
#a[min] in %ecx ;a in %edx Y2$wL9">  
xorl    %ecx, %edx `O ,^oD4  
movl    %edx, -16(%rbp,%rax,4) U-+o6XX  
#put it back in a[min] *3@ =XY7  
movslq  -24(%rbp), %rax \0 j-p   
#i=0 in %rax Z; 6N7U  
movl    -16(%rbp,%rax,4), %ecx ly9tI-E  
#a in %ecx d#(ffPlq  
xorl    %edx, %ecx K]SsEsd  
#xorl a with the result of a[min]^a WQiIS0BJ *  
movl    %ecx, -16(%rbp,%rax,4) {Qba`lOkq  
#put it back in a,now we put the original a[min] in a+i #IvHxSo&  
movslq  -20(%rbp), %rax mswAao<y&x  
#min=1 in %rax `;Od0uh  
movl    -16(%rbp,%rax,4), %edx (&i c3/-  
#a[min] in %edx,this a[min] differs from the origin, F FtB#  
#it is the result of the original a^a[min] 7TtDI=f  
xorl    %ecx, %edx `T,^os#6  
#original a[min] in %ecx and the original a^a[min] in %edx kD46Le++B  
movl    %edx, -16(%rbp,%rax,4) }D]y -BbA.  
#put it back in a[min],now we put the original a in a+min |mQC-=6t;Y  
movslq  -24(%rbp), %rax ~KYA{^`*  
movl    -16(%rbp,%rax,4), %esi .4J7 ^l  
movslq  -20(%rbp), %rax  )mH(Hx  
movl    -16(%rbp,%rax,4), %edx K BlJJH`z{  
#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 ,看看: [y| "iSD  
http://ideone.com/vmPSAw BEyg 63=  
(Bd8@}\u_  
是否问题出在代码之外的错误,比如编译的和运行的不是同一个版本之类的问题?
级别: 北风资深评论员


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


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

我不知道那本书为什么这么说,但是我觉得大多数编译器都不是按照那本书来实现的。 ./<giTR:p  
h(i_'P?  
a[min]^=a^=a[min]^=a; !FQS9SoO9  
等于 O4!!*0(+91  
lI3d _cU  
a[min]^=(a^=(a[min]^=a));  `ghNS   
等于 ;,Os3  
JHuA} f{2&  
a[min] = a[min] ^ a  ; /px`FuJI(  
a   = a   ^ a[min]; u&'&E   
a[min] = a[min] ^ a  ;