在C语言编程章节中,交换两个数的数值是一个经典的话题。但是仅仅的就交换连个数的值还是有很多值得学习的细节和技巧。
先设定一个开始:
#include<stdio.h>
void change_1(int,int);
void change_2(int*,int*);
void change_3(int *,int*);
void change_4(int *,int *);
int main(int argc,char **argv)
{
int a=3,b=4;
//change_4(&a,&b);
printf("a=%d\t b=%d\t\n",a,b);
return 0;
}
change_x为我们要调用的函数下面分别解释:
1.常规的交换两个数change_1(但达不到理想的效果)
void change_1(int x,int y)
{
int b;
b=x;
x=y;
y=b;
}
在执行完毕之后会发现a和b的值并没有发生改变:a=3,b=4。这是因为在函数调用的过程中,change_1只是简单的复制了相关的数值,并没有对原地址的数据进行有效改变。在函数调用过程中内存会重新开辟空间,同时将a和b的值分别复制给x和y。在开辟的内存空间中x和y分别赋予了a和b的值同时执行了交换。但函数执行完毕并返回时,开辟的内存空间自动销毁,而主函数中a和b的值并没有发生改变。(这里只做加单介绍,深入的分析在后文中会进一步继续:分析汇编代码)
2.常见的交换两个数change_2(有效而直观)
void change_2(int *x,int *y)
{
int a;
a=*x;
*x=*y;
*y=a;
}
在执行change_2之后会发现达到了理想的目的:a=4,b=3。在书本中我们称之为“将实参的地址传递给函数”。简单的理解就是,使用地址或指针,我们直接将原函数中的数值在新开辟的函数中进行直接换算。虽然开辟了空间,但在传递数值的过程中,调用的是原地址中的数据,这样即使函数执行完毕之后销毁,但数值已经发生了改变。
(以上两种后期会通过汇编代码补充分析)
3.第一种技巧:加法运算chege_3
void change_3(int *x,int *y)
{
*x=*x+*y;
*y=*x-*y;
*x=*x-*y;
}
4.第二种技巧:位运算change_4
void change_4(int *x,int *y)
{
*x=*x^*y;
*y=*x^*y;
*x=*x^*y;
}
位运算原理在于:a^a=0
(a^b)^a=(a^a)^b=0^b=b
(a^b)^b=a^(b^b)=a^0=a