现在有一个程序需要无论输入哪三个数都得从大到小输出,大部分人都会想到两两比较再依次赋值的方法,也就是冒泡法,冒泡法的程序如下
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//冒泡法求最大
int main()
{
int a = 0;
int b = 0;
int c = 0;
scanf("%d%d%d", &a, &b, &c);
if (a < b)
{
int temp = 0;
temp = b;
b = a;
a = temp;
}
if (a < c)
{
int temp = 0;
temp = c;
c = a;
a = temp;
}
if (b < c)
{
int temp = 0;
temp = c;
c = b;
b = temp;
}
printf("%d %d %d", a, b, c);
return 0;
}
可以看到如果我们输入11 22 33 看看输出结果是什么
![]()
利用这种方法很容易的就可以按照顺序输出从大到小的值,只需注意调换的时候需要一个临时变量temp来存储数据就可以了,但是我们可以发现,其中三段比较代码都非常的相似,那我们可不可以写一个函数来实现这个比较大小赋值的操作呢?答案是当然可以的,如果还没有足够了解函数,可能写出的代码会出一点错误,比如像下面这样
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//未利用传址写出来的函数
void get_big(int x,int y)
{
if (x < y)
{
int temp = 0;
temp = y;
y = x;
x = temp;
}
}
int main()
{
int a = 0;
int b = 0;
int c = 0;
scanf("%d%d%d", &a, &b, &c);
get_big(a, b);C
get_big(a, c);
get_big(b, c);
printf("%d %d %d",a, b, c);
return 0;
}
我们尝试输入11 22 33 看看输出的结果是什么
![]()
利用我们自定义的get_big的函数我们并未实现从大到小的输出,我们可以按F11逐步调试看看是哪一步出了问题
经过调试可以看到,在主函数进入get_big函数内部的时候,里面的x,y确实是有进行交换的,但是主函数的a和b并未进行交换,这就奇怪了,到底是怎么回事呢?

这就涉及到我们函数的传值和传址调用了,其实如果我们仅仅让两个变量进入函数内部,我们只是选取了两个变量的值,但是存放需要改变两个变量的并未发生改变,因为传入的get_big函数内部重新又定义了两个变量x和y,只是改变了它们的值,我们计算机又为它们两个创造了地址,改变的是x、y地址的值,而并未改变a和b这两个地址内存放的值。
那如何利用函数来实现这个操作呢?其实很简单,如果我们传入函数的是a和b的地址,直接改变它们的内存地址的值不就可以了吗?依照这个思想,我们来试一下
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//使用传址写出来的函数
void get_big(int* x, int* y)
{
if (x < y)
{
int temp = 0;
temp = *y;
*y = *x;
*x = temp;
}
}
int main()
{
int a = 0;
int b = 0;
int c = 0;
scanf("%d%d%d", &a, &b, &c);
get_big(&a, &b);
get_big(&a, &c);
get_big(&b, &c);
printf("%d %d %d", a, b, c);
return 0;
}
我们传递a、b的地址然后还是输入11 22 33看一下结果

可以看到利用这串代码写出来的程序既可以按照顺序输出从大到小的值。
这就是传址调用和传值调用的区别,传值调用改变的只是里面的形参,而我们的实参其实从未改变,如果要改变我们的实参得输入传址调用的方式。





