可能是重复问题:
从函数返回多个值
假设我向一个函数iCalculate(int x, int y)
传递了两个值,并且这个iCalculate
函数返回两个值,它们分别是:
(x*y)
(x/y)
现在我应该如何通过同一个函数同时返回上述两个值?
我的方法是:
int* iCalculate(int x,int y){
int temp[2];
temp[0] = x*y;
temp[1] = x/y;
return temp;
}
返回本地数组第一个元素的地址具有未定义行为(至少稍后解引用它时是如此)。
您可以使用输出参数,也就是传递两个指针,并在内部设置值。
void Calculate(int x, int y, int* prod, int* quot)
{
*prod = x*y;
*quot = x/y;
}
用法:
int x = 10,y = 2, prod, quot;
Calculate(x, y, &prod, ")
你可以做的另一件事是将你的数据打包到一个结构体中。
typedef struct
{
int prod;
int quot;
} product_and_quot;
product_and_quot Calculate(int x, int y)
{
product_and_quot p = {x*y, x/y};
return p;
}
struct
选项,我的速度并不比我快。C程序员为什么总是先考虑指针解决方案,而将简单的解决方案放在第二位呢?;) - Fred Foostruct
,使客户端负责分配内存时才会出现这种情况。让我们看看我们能得到什么:我们不再复制两个32位整数,而是仅复制单个32位指针。并且这只需要额外的一个声明、一个 &
操作符和两个解引用。不,等等,32位指针?那是昨天年代的硬件了... - Fred Foostruct
是一个有效的观点,但不适用于这种数学函数,因为你知道将返回什么。 - Fred Foo那样是行不通的,因为你返回了一个指向临时数组的指针,在函数返回时会停止存在。
相反,定义
typedef struct { int first, second; } IntPair;
并返回该类型的一个对象。
(这就是标准库函数 div
和 ldiv
所做的事情,只不过它们以不同的方式调用该类型。)
div
和 ldiv
。大多数其他函数都通过指针返回,尽管在现代计算机上这并不是必要的(它曾经是一种优化方法)。 - Fred Footemp
已经超出了其作用域或不存在。因此,您不应该返回temp
的地址。这将是一个超出作用域或不存在变量的地址。访问该地址意味着未定义的行为。void iCalculate(int x,int y,int *mult,int *divi){
*mult = x*y;
*divi = x/y;
}
typedef struct{
int mul, divi;
} TResult;
TResult iCalculate(int x,int y){
TResult res;
res.mul = x*y;
res.divi = x/y;
return res;
}
void iCalculate(int x,int y,TResult *res){
res->mul = x*y;
res->divi = x/y;
}
我建议采用第一种方法。我认为创建一个新的结构体定义只是为了将两个不相关的值封装在一起太傻了。
int temp[2]
就会消失,所以调用者会有一个“悬空”的指针。你必须添加 static
。另一种更好的方式是让调用者传递它想要存储结果的位置。void iCalc(int x, int y, int *rp, int *rq)
{
// check if rp and rq are NULL, if so, returns
*rp = x*y;
*rq = x/y; // y != 0, and this will truncate of course.
}
而调用者将会执行类似的操作
int res[2];
iCalc(x, y, res, res+1);
或类似。
你的方法不是完全错误的,你可以这样返回表的地址:
int *iCalculate(int x,int y){
int *temp=malloc(sizeof(int)*2);
temp[0]=x*y;
temp[1]=x/y;
return temp;
}
别忘了释放内存:
int *result;
result=iCalculate(10,7);
printf("%d %d\n",result[0],result[1]);
free(result);