首页 > 代码库 > 从交换两个变量值看c语言学习历程

从交换两个变量值看c语言学习历程

在开始你使用这种方法
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: hellojukay@gmail.com 
    > 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字符还好说,可是如果遇到了浮点数怎么办,结构体怎么办?难道重新写一个函数吗,接下来我们要学习的就是泛型编程了,只有这样,我们写的程序才能以不变应万变.我们的取经之路刚刚开始呢!!!

从交换两个变量值看c语言学习历程