使用多个return语句
这是最容易想到的,有多个返回值就想当然以为可以写多个return实现。下面我们来测试下:
#include <stdio.h>
int findMaxAndMin(int a, int b, int c)
{
int temp = a>b?(temp=a):(temp=b);
int max = temp>c?temp:c;
int temp1 = a<b?(temp1=a):(temp1=b);
int min = temp1<c?(temp1):c;
return max;
return min;
}
int main(void)
{
int a, b, c;
scanf("%d,%d,%d", &a, &b, &c);
printf("The max value is: %d\n", findMaxAndMin(a, b, c));
printf("The min value is: %d\n", findMaxAndMin(a, b, c));
return 0;
}
- #include <stdio.h>
- int findMaxAndMin(int a, int b, int c)
- {
- int temp = a>b?(temp=a):(temp=b);
- int max = temp>c?temp:c;
- int temp1 = a<b?(temp1=a):(temp1=b);
- int min = temp1<c?(temp1):c;
- return max;
- return min;
- }
- int main(void)
- {
- int a, b, c;
- scanf("%d,%d,%d", &a, &b, &c);
- printf("The max value is: %d\n", findMaxAndMin(a, b, c));
- printf("The min value is: %d\n", findMaxAndMin(a, b, c));
- return 0;
- }
#include <stdio.h>
int findMaxAndMin(int a, int b, int c)
{
int temp = a>b?(temp=a):(temp=b);
int max = temp>c?temp:c;
int temp1 = a<b?(temp1=a):(temp1=b);
int min = temp1<c?(temp1):c;
return max;
return min;
}
int main(void)
{
int a, b, c;
scanf("%d,%d,%d", &a, &b, &c);
printf("The max value is: %d\n", findMaxAndMin(a, b, c));
printf("The min value is: %d\n", findMaxAndMin(a, b, c));
return 0;
}

我们虽然在findMaxAndMin()函数中写了两个return语句。但通过printf测出函数的返回值,是只返回了一个值。
如果我们将两个return语句颠倒下呢?
#include <stdio.h>
int findMaxAndMin(int a, int b, int c)
{
int temp = a>b?(temp=a):(temp=b);
int max = temp>c?temp:c;
int temp1 = a<b?(temp1=a):(temp1=b);
int min = temp1<c?(temp1):c;
return min;
return max;
}
int main(void)
{
int a, b, c;
scanf("%d,%d,%d", &a, &b, &c);
printf("The max value is: %d\n", findMaxAndMin(a, b, c));
printf("The min value is: %d\n", findMaxAndMin(a, b, c));
return 0;
}
- #include <stdio.h>
- int findMaxAndMin(int a, int b, int c)
- {
- int temp = a>b?(temp=a):(temp=b);
- int max = temp>c?temp:c;
- int temp1 = a<b?(temp1=a):(temp1=b);
- int min = temp1<c?(temp1):c;
- return min;
- return max;
- }
- int main(void)
- {
- int a, b, c;
- scanf("%d,%d,%d", &a, &b, &c);
- printf("The max value is: %d\n", findMaxAndMin(a, b, c));
- printf("The min value is: %d\n", findMaxAndMin(a, b, c));
- return 0;
- }
#include <stdio.h>
int findMaxAndMin(int a, int b, int c)
{
int temp = a>b?(temp=a):(temp=b);
int max = temp>c?temp:c;
int temp1 = a<b?(temp1=a):(temp1=b);
int min = temp1<c?(temp1):c;
return min;
return max;
}
int main(void)
{
int a, b, c;
scanf("%d,%d,%d", &a, &b, &c);
printf("The max value is: %d\n", findMaxAndMin(a, b, c));
printf("The min value is: %d\n", findMaxAndMin(a, b, c));
return 0;
}

返回的是最小值。由此可见:
使用两个return语句是无法让函数返回两个以上的值。并且编译器只会看到第一个return并将值返回给主调函数,然后就会认为已经将函数执行完毕。不会理会第二个return语句。
方法一:使用全局变量
在findMaxAndMin()函数中,保存最大值和最小值的变量是max和min。它们默认是局部变量,只在函数中有效。
如果将其声明为全局变量,我们就可以在整个程序中利用这两个全局变量。间接的实现让函数返回两个值的操作。
#include <stdio.h>
int max, min;
void findMaxAndMin(int a, int b, int c)
{
int temp = a>b?(temp=a):(temp=b);
max = temp>c?temp:c;
int temp1 = a<b?(temp1=a):(temp1=b);
min = temp1<c?(temp1):c;
}
int main(void)
{
int a, b, c;
scanf("%d,%d,%d", &a, &b, &c);
findMaxAndMin(a, b, c);
printf("The max value is: %d\n", max);
printf("The min value is: %d\n", min);
return 0;
}
- #include <stdio.h>
- int max, min;
- void findMaxAndMin(int a, int b, int c)
- {
- int temp = a>b?(temp=a):(temp=b);
- max = temp>c?temp:c;
- int temp1 = a<b?(temp1=a):(temp1=b);
- min = temp1<c?(temp1):c;
- }
- int main(void)
- {
- int a, b, c;
- scanf("%d,%d,%d", &a, &b, &c);
- findMaxAndMin(a, b, c);
- printf("The max value is: %d\n", max);
- printf("The min value is: %d\n", min);
- return 0;
- }
#include <stdio.h>
int max, min;
void findMaxAndMin(int a, int b, int c)
{
int temp = a>b?(temp=a):(temp=b);
max = temp>c?temp:c;
int temp1 = a<b?(temp1=a):(temp1=b);
min = temp1<c?(temp1):c;
}
int main(void)
{
int a, b, c;
scanf("%d,%d,%d", &a, &b, &c);
findMaxAndMin(a, b, c);
printf("The max value is: %d\n", max);
printf("The min value is: %d\n", min);
return 0;
}

是可以实现需求的。但使用全局变量的缺点是,这个定义在外面的max和min是可以在这个文件中的任何地方被使用的。如果其他函数使用了全局变量,例如重新复制,那么它的值就会改变。这显然是不安全的,并且会使得代码的耦合度升高。不利于后期维护和代码调试。
方法二:使用指针变量
参考:如何让一个函数返给主函数多个返回值
方法三:利用数组
错误思想:被调函数计算出两个值max和min后,可以用一个数组保存起来,然后返回给主调函数这个数组的地址,主调函数再经过处理(指针运算,拿出里面的值)。
原因:试图让被调函数返回地址就是错误的。因为被调函数在执行完毕后,就弹栈了,所占用的空间就被释放。(即垃圾地址)。让主调函数操作那个垃圾地址是得不到正确的值的。
举例:你租了一间404房间,一天后你走了,但是你在退房前告诉你的朋友在404房间有一本书,第二天你退房后,你的朋友通过404这个地址是能找到这个房间的,但那本书可能在也可能不在,这就不一定了。
正确方法:在调用被调函数之前就将参数(本题是三个参数)存在一个数组中,然后将数组的地址传递给被调函数,让其通过指针来改变它们的位置(例如最小的在0号下标位置,最大的在2号下标位置)。如图:
#include <stdio.h>
void findMaxAndMin(int *pArr, int n) //传数组给函数需要两个参数(数组名和数组长度)
{
//排序
for (int i = 0; i<n-1; i++)
{
for (int j = 0; j<n-i-1; j++)
{
if (pArr[j]>pArr[j+1])
{
int temp = pArr[j];
pArr[j] = pArr[j+1];
pArr[j+1] = temp;
}
}
}
}
int main(void)
{
int arr[3];
for (int i = 0; i<3; i++)
{
scanf("%d", &arr[i]);
}
findMaxAndMin(arr, 3);
printf("The max value is: %d\n", arr[2]);
printf("The min value is: %d\n", arr[0]);
return 0;
}
- #include <stdio.h>
- void findMaxAndMin(int *pArr, int n) //传数组给函数需要两个参数(数组名和数组长度)
- {
- //排序
- for (int i = 0; i<n-1; i++)
- {
- for (int j = 0; j<n-i-1; j++)
- {
- if (pArr[j]>pArr[j+1])
- {
- int temp = pArr[j];
- pArr[j] = pArr[j+1];
- pArr[j+1] = temp;
- }
- }
- }
- }
- int main(void)
- {
- int arr[3];
- for (int i = 0; i<3; i++)
- {
- scanf("%d", &arr[i]);
- }
- findMaxAndMin(arr, 3);
- printf("The max value is: %d\n", arr[2]);
- printf("The min value is: %d\n", arr[0]);
- return 0;
- }
#include <stdio.h>
void findMaxAndMin(int *pArr, int n) //传数组给函数需要两个参数(数组名和数组长度)
{
//排序
for (int i = 0; i<n-1; i++)
{
for (int j = 0; j<n-i-1; j++)
{
if (pArr[j]>pArr[j+1])
{
int temp = pArr[j];
pArr[j] = pArr[j+1];
pArr[j+1] = temp;
}
}
}
}
int main(void)
{
int arr[3];
for (int i = 0; i<3; i++)
{
scanf("%d", &arr[i]);
}
findMaxAndMin(arr, 3);
printf("The max value is: %d\n", arr[2]);
printf("The min value is: %d\n", arr[0]);
return 0;
}

Ps:上述排序使用的是冒泡法,使用其他的排序算法也是可以的。
方法四:利用结构体
既然使用数组是可以的,我们可以把使用数组的方法看作把需要操作的数据打包起来,用指针来操作和改变内部的值。
下面尝试下用结构体来打包一组数据。
#include <stdio.h>
struct Arr {
int num1, num2, num3;
int min;
int max;
};
void findMaxAndMin(struct Arr *pArr) //传数组给函数需要两个参数(数组名和数组长度)
{
int t = pArr->num1>pArr->num2?pArr->num1:pArr->num2;
pArr->max = t>pArr->num3?t:pArr->num3;
int t1 = pArr->num1<pArr->num2?pArr->num1:pArr->num2;
pArr->min = t1<pArr->num3?t1:pArr->num3;
}
int main(void)
{
struct Arr arr;
//赋值
arr.num1 = 2;
arr.num2 = -4;
arr.num3 = 8;
findMaxAndMin(&arr); //传地址到函数
printf("The max value is: %d\n", arr.max);
printf("The min value is: %d\n", arr.min);
return 0;
}
- #include <stdio.h>
- struct Arr {
- int num1, num2, num3;
- int min;
- int max;
- };
- void findMaxAndMin(struct Arr *pArr) //传数组给函数需要两个参数(数组名和数组长度)
- {
- int t = pArr->num1>pArr->num2?pArr->num1:pArr->num2;
- pArr->max = t>pArr->num3?t:pArr->num3;
- int t1 = pArr->num1<pArr->num2?pArr->num1:pArr->num2;
- pArr->min = t1<pArr->num3?t1:pArr->num3;
- }
- int main(void)
- {
- struct Arr arr;
- //赋值
- arr.num1 = 2;
- arr.num2 = -4;
- arr.num3 = 8;
- findMaxAndMin(&arr); //传地址到函数
- printf("The max value is: %d\n", arr.max);
- printf("The min value is: %d\n", arr.min);
- return 0;
- }
#include <stdio.h>
struct Arr {
int num1, num2, num3;
int min;
int max;
};
void findMaxAndMin(struct Arr *pArr) //传数组给函数需要两个参数(数组名和数组长度)
{
int t = pArr->num1>pArr->num2?pArr->num1:pArr->num2;
pArr->max = t>pArr->num3?t:pArr->num3;
int t1 = pArr->num1<pArr->num2?pArr->num1:pArr->num2;
pArr->min = t1<pArr->num3?t1:pArr->num3;
}
int main(void)
{
struct Arr arr;
//赋值
arr.num1 = 2;
arr.num2 = -4;
arr.num3 = 8;
findMaxAndMin(&arr); //传地址到函数
printf("The max value is: %d\n", arr.max);
printf("The min value is: %d\n", arr.min);
return 0;
}

这里强调下,第11到第15行是算法,作用是找到最大的值和最小的值。具体利用的是三目运算符(相当于两个if…else语句),如果不理解可以把这段代码改成其他的找最大最小值算法。或者用冒泡、选择等排序算法实现。
本篇文章重点不是讲解这些排序算法,往后我会抽时间专门出一篇排序算法总结。
到了这里,基本上常见的使函数返回多个值的方法就介绍完毕了。如果大家有更好的办法欢迎补充。谢谢!