在开始你使用这种方法
int tmp; tmp = a; a = b; b = tmp;
后来你知道了模块化编程,你知道这样是不好的,于是你开始使用函数.
void swap(int *a, int *b); { int tmp; tmp = *a; *a = *b; *b =tmp; }//下面我就不写函数了
随着c语言的学习,后来你发现下面代码也能完成两变量的值交换的任
x = x +y; y = x -y; x = x -y;
后来有一天,你发现你这段代码不是总能正确工作的,因为x + y的值可能一出了啊.
类似的除法和乘法是不是也可以进行这样的交换能
x = x * y; y = x / y; x = x / y;
聪明的你很快就发现了,这里隐藏了两个bug.如果x*y = 0怎么办,x*y溢出来怎么办,也就是说只要其中有一个是0就不能处理了,程序还会因为除以0而异常退出.
后来你看到了一串代码
x = x^y; y = x^y; x = x^y;
别人说这也能交换值,你不相信,这是什么玩意,异或运算怎么交换两个数的值?是什么原理
下面说说异或运算的几条规律:
1.任何数字与1异或的结果都是这个数字的取反的结果,反之亦然.
例如:
x = x ^ 1;//等价下面语句 x = ~x; 原理如下: 1 = 1 ^ 0; 1 = 0 ^ 1; 0 = 1 ^ 1;
2.任何数字与0运货算法的结果是他本身,反之亦然.
例如:
x = x ^ 0 ;//等价下面语句 x = x; 原理如下: 0 = 0 ^ 0; 1 = 0 ^ 1; 1 = 1 ^ 0;
3.一个数异或他自己的结果总是0.
为了加深理解,让我们来写一个小程序:
/************************************************************************* > File Name: test.c > Author: 傻李 > Mail: [email protected] > Created Time: 2014年11月23日 星期日 11时50分03秒 ************************************************************************/ #include<stdio.h> int main() { int x =3,y =4; int t; printf("(%d,%d)\n",x,y); t = x ^ y; x = x ^ t; y = x ^ t; printf("(%d,%d)\n",x,y); return 0; }
int x = 3; int y = 4; int tmp; tmp = x ^ y; y = t ^ y;//y = (x ^ y) ^ y ->> y = x ^ y ^ y ->> y = x ^ 0; ->> y = x;//此时y的值已经变为x x = t ^ x; x = (x ^ y) ^ x; ->> x= x ^ x ^ ; x = y; 带入数值来运算一遍: tmp = 3 ^ 4; y = tmp ^ y = (3 ^ 4) ^ 4 = 3; x = tmp ^ x = (3 ^ 4) ^ 3 = 4;
呵呵,tmp = x + y;是不是很像宏呢?你看他只是等价的替换.确实有微妙的相似.
现在不难理解下面代码了吧.
x = x ^ y; y = x ^ y; x = x ^ x;
于是下面代码也是不难理解的:
a ^= b ^= a ^= b;//为了防止被乱棍打死,还是不要写这种代码了
好像到了这里,你已经精通交换两变量的各种方法了,实际上路还遥远的很呢,上面所说都只是交换连个整数的例子,遇到ASCII字符还好说,可是如果遇到了浮点数怎么办,结构体怎么办?难道重新写一个函数吗,接下来我们要学习的就是泛型编程了,只有这样,我们写的程序才能以不变应万变.我们的取经之路刚刚开始呢!!!
时间: 2024-10-12 03:59:25