想要交换参数,如果不用无返回值的函数类型。有几种办法可以实现,可以在主函数里加一点东西,比如定义两个变量a和b,要交换他们,可以让函数返回一个b,用a来接收,然后让函数返回一个a,让b来接收。
要么就在主函数里在定义一个临时变量tmp,用来暂时接收一个变量
typedef int(*swap)
当有两个数需要交换怎么办?简单!!通过一个额外的变量当做临时参数就可以
比如
int i = 3;
int j = 5;
//我现在想交换i和j,那么就定义另外一个变量
int tmp;
tmp = i;
i = j;
j = tmp
这样就实现了两个变量值的交换。
但是我们很多时候并不能在主函数里写太多东西,为了模块化的思想,也为了能够写一个东西可以让其它的函数调用,那么我们就需要写一个函数叫做swap来交换两个参数
但要注意的是由于交换变量,如果函数要返回值,必须只能返回一个值,而这里想返回两个参数所以只能用void型函数。
void的注意函数在使用之后参数都会被释放掉。
1.最普通的值传递
void swap(int x,int y)
{int tmp;
tmp = x;
x = y;
y = tmp;
}
如果没有下面的东西,可能很多同学都会认为这是对的,包括我,我真的是搞了很久很久才有一些感觉。但如果你知道为什么这个不对以及不对的原因,那么恭喜你,已经初步了解了指针。而且这篇文章也不用继续阅读。 ^_^
但如果不了解的话请慢慢观看哦~。
(gdb) print &x
$1 = (int *) 0x7fffffffe088
(gdb) print &y
$2 = (int *) 0x7fffffffe08c
(gdb) n
Breakpoint 1, swap (x=3, y=4) at test.c:7
7 tmp = x;
(gdb) print &x
$3 = (int *) 0x7fffffffe04c
(gdb) n
8 x = y;
(gdb)
9 y = x;
(gdb) print &y
$4 = (int *) 0x7fffffffe048
函数传进来的值其实是一份内存的拷贝,为了真实性,拿gdb调试了一下,看到了么,两个x的地址是不一样的.
比如我在主函数里定义一个变量x,那么给函数的参数就变成_x,值一样,但是是用另外一块内存存储的。
那么很显然,我把地址0x7fffffffe04c单元上存储的值改变,但是0x7fffffffe088上的东西没变呀。说明值传递不可以。
2.地址传递
void swap1(int *x,int *y){
int *tmp;
tmp = x;
x = y;
y = tmp;
}
换一个思路,传递一个地址值,直接告诉大家结果,这个是可以的,为什么呢?
参数传进来的是指针x的地址,按照刚才的理论:存储指针x的空间,参数和实际的是不一致的(你把值换成地址看就肯定明白了)
但是我的地址就是那个x的地址,这个肯定没问题,那么,我现在改变地址上面的值,你说还能不行吗!! ^_^
当然,指针变量其实就是存储的一个地址。在给参数的时候记得给的是地址哦
void swap3(void *p,void *q,size_t size){
unsigned char *x = p;unsigned char *y = q;
unsigned char tmp;
while(size--){
tmp = *p;
*p = *q;
*q = tmp;
p++;
q++;
}
}
了解了指针,现在可以看一下应用场景广泛的编程示范。变量传进来可能是char,int,long。。。。那怎么办呢?
就需要上面这种办法了!!void *是一个空类型指针,它可以接收所有的指针类型,但如果要转换为别的类型,需要强制类型转换,虽然c没有那么多的限制,但是作为良好的编程习惯,还是应该强转一下。size_t是unsigned int类型。size表示接收的多少byte。
5.通过位运算交换:
{
*p = *p ^ *q;
*q = *q ^ *p;
*p = *p ^ *q;
}
位运算是很神奇的东西!!为什么通过这个可以实现变换呢!^_^
^的意思就是两者一样就为0,不一样就为1
那么0^1 == 1
0^0 == 0
0^1^0 == 0^0^1 == 1
所以看见了把,a^b^a ==b
b^a^b == a
愉快撸码,快乐人生。今天就到这里了。喜欢的话关注我哦!