在一般的C语言函数中,函数的返回值只能是一个值。那么可不可以让函数返回多个值呢,我们来讨论。为此,我们设置一个场景,计算两个数的和与差。
一、函数只能返回一个值
如下面的两个函数,一个是求和函数my_add(),一个是求差函数my_minus()函数。
实验一:只有一个返回值的函数求和差
代码如下:
/* one_return.c */
#include <stdio.h>
/* 求和函数 */
int my_add(int a, int b)
{
int temp;
temp = a + b;
return temp;
}
/* 求差函数 */
int my_minus(int a, int b)
{
int temp;
temp = a - b;
return temp;
}
int main(void)
{
int num_1,num_2; // 保存操作数
int ret; // 保存结果
char ope; // 保存操方式
printf("Enter number 1: ");
scanf("%d", &num_1);
printf("Enter number 2: ");
scanf("%d", &num_2);
printf("Enter operation way: "); // 输入操作方式
scanf(" %c", &ope);
switch(ope) {
case '+':
ret = my_add(num_1, num_2);
break;
case '-':
ret = my_minus(num_1, num_2);
break;
default:
break;
}
printf("----------------------------------------\n");
printf("The result = %d\n", ret);
return 0;
}
编译:
gcc one_return.c -o one_return.exe
运行后结果为:
这里每个函数只能返回一个值,如果强行返回两个值,如下实验二。
实验二:强行返回两个值
代码如下:
/* multi_return_error.c */
#include <stdio.h>
/* 求和差函数*/
int my_add_minus(int a, int b)
{
int temp1, temp2;
temp1 = a + b;
temp2 = a - b;
return (temp1, temp2);
}
int main(void)
{
int num_1,num_2; // 保存操作数
int ret; // 保存结果
printf("Enter number 1: ");
scanf("%d", &num_1);
printf("Enter number 2: ");
scanf("%d", &num_2);
ret = my_add_minus(num_1, num_2);
printf("The result = %d\n", ret);
return 0;
}
编译如下:
gcc multi_return_error.c -o multi_return_error.exe
编译过程没有任何错误:
但是执行效果如下:
返回的为temp2即a-b的值,这里实际返回的减法值。
这里是逗号表达式在作怪。看下面实验三。
实验三:逗号表达式
/* comma_expression.c */
#include <stdio.h>
int main(void)
{
int a, b;
int x = 12, y = 23, z = 34;
a = (2,3,5,6);
b = (x,y,z);
printf("a = %d, b = %d\n",a , b);
return 0;
}
编译:
gcc comma_expression.c -o comma_expression.exe
执行为:
可以看到逗号表达式返回的是最后连缀起来的最后一个值。
如果我们将上面实验三中逗号表达式的括号去掉,如实验二的代码中函数my_add_minus()的return语句般书写,代码如下:
/* comma_expression_2.c */
#include <stdio.h>
int main(void)
{
int a, b;
int x = 12, y = 23, z = 34;
a = 2,3,5,6;
b = x,y,z;
printf("a = %d, b = %d\n",a , b);
return 0;
}
此时,编译输出后为:
返回的是逗号中第一个值,这是由于赋值符号(=)的优先级高于逗号(,)其实如下代码:
a = 2,3,5,6;
返回的是逗号中第一个值,这是由于赋值符号(=)的优先级高于逗号(,)其实等效于如下代码:
(a = 2),3,5,6;
是先将2赋值给a之后,在组成逗号表达式语句。
C语言中,优先级低于赋值运算符(=)的唯一一个运算符就是逗号运算符(,)。
现在我们的问题是,如果要得到多个返回值,要怎么处理?
二、函数返回多个值——方式一:指针+数组
我们现在利用指针方式,将加减乘除同时写入到一个函数中,其实就是建立这样一个int型数组,其中用于保存得到的和差积商,将数组地址作为参数传递。
数组中结构如下:
实验四:指针方式函数返回多个值
代码如下:
/* multi_return_array.c */
#include <stdio.h>
#include <malloc.h>
/* 返回和差积商函数 */
int * my_return_by_array(int a, int b)
{
int * ret_arr = (int *)malloc(4*sizeof(int));
*(ret_arr + 0) = a + b;
*(ret_arr + 1) = a - b;
*(ret_arr + 2) = a * b;
*(ret_arr + 3) = a / b;
return ret_arr;
}
int main(void)
{
int num_1,num_2; // 保存操作数
int * ret; // 保存结果
printf("Enter number 1: ");
scanf("%d", &num_1);
printf("Enter number 2: ");
scanf("%d", &num_2);
ret = my_return_by_array( num_1, num_2);
printf("The result:\n%8d, %8d, %8d, %8d\n", ret[0], ret[1],ret[2],ret[3]);
return 0;
}
编译,运行如下:
三、函数返回多个值——方式二:结构体
利用结构体的值传递特性,可以得到返回多个值的函数。
实验五:结构体方式函数返回多个值
代码如下:
/* multi_return_struct.c */
#include <stdio.h>
/* 定义保存和差积商的结构体 */
struct my_retrun {
int sum;
int defference;
int product;
int quotient;
};
/* 返回和差积商函数 */
struct my_retrun my_return_by_array(int a, int b)
{
struct my_retrun ret_struct;
ret_struct.sum = a + b;
ret_struct.defference = a - b;
ret_struct.product = a * b;
ret_struct.quotient = a / b;
return ret_struct;
}
int main(void)
{
int num_1,num_2; // 保存操作数
struct my_retrun ret; // 保存结果
printf("Enter number 1: ");
scanf("%d", &num_1);
printf("Enter number 2: ");
scanf("%d", &num_2);
ret = my_return_by_array( num_1, num_2);
printf("The result:\n%8d, %8d, %8d, %8d\n", ret.sum, ret.defference, ret.product,ret.quotient);
return 0;
}
编译运行:
四、结论
1、一般的函数只能返回一个值
2、如果要返回多个值,可以采用如下两种简单的方式,一个是指针+数组方式,一个是结构体方式。
3、更高级点的方法是采用链表方式。