笔记一 2.1.8异或交换产生的问题

博客一放,又是好久没有写了。。。。

前两天买了两本砖头书回来。一本是《深入理解计算机系统》第二版的的中文版,另一本便是《算法导论》第三版的中文版。打算花时间认认真真消化完这两本书。再结合自己几年的工作经验,根据理论,做一些分析,力争找到问题的本源,以及解决办法,多写几句没事,争取把问题讲透。另外一点,便是想把不扎实的知识点,通过阅读这本书,把东西吃透。需要整理的代码,自己扔在csdn的git托管中。今天分析的这个代码的源文件是2.1.8-swap.c,可以参考一下。

今天主要是看到书的2.1.8节,C语言的位运算中。聊到了用异或实现a和b数据交换的问题。实际上这个函数在实际应用上,并没有多少价值,但最主要的是加深原理性的理解。

void swap(int *x, int *y){
    *y = *x ^ *y; 
    *x = *x ^ *y; 
    *y = *x ^ *y; 

}

说实话,单看这段代码,也不会出现问题。我原来印象出,一直觉得是溢出会产生的问题。但是自己写代码验证过,溢出并没有产生问题。读了文章中,才反应过来这个函数真的会出现问题。但是如果不是看到练习题2-11,我真的还想不到哪儿出了问题。。。。

异或交换的依据是a^b^a = b,然后有一个加法逆元的结论,a^a= 0。我联想起来,用加减去做swap的一个例子。

void swap2(int *x, int *y){
    *x = *x + *y;
    *y = *x - *y;
    *x = *x - *y;
}

实现原理也跟加法逆元的概念有关。a+b-a = b,同异或a-a = 0 那么,如果不用第三个数,做数据交换,只要他有加法逆元,即这个数与它本身的运算,结果为0。就可以用做数据交换来使用。
看到还有一句话的实现

a = b+a - ( b=a );

实际上也是用了加法逆元的特性,写法不一样,原理是一样的。

也是正因为这一个特性,导致数组逆序时,产生了问题。在逆序的数组为奇数时,最后变成了自己交换。然后a^a=0的副作用这时候就显现出来了。a-a=0的副作用也同样。。。
书中的要求修改的代码,我也改过,仍然放在2.1.8-swap.c这个文件中,可以做参考。规避掉奇数个的数组逆序时产生的问题。

这个问题就分析到这里,后面力争在每一个问题上,都挖出源头。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值