从C函数返回多个值

时间:2009-07-06 18:49:52

标签: c data-structures

重要:请参阅以下相关问题:Return multiple values in C++

我是如何在ANSI C中做同样的事情的?你会使用结构或传递函数中的参数的地址吗?我追求极其高效(快速)的代码(时间和空间),即使以可读性为代价。

编辑:感谢您的所有答案。好吧,我想我有一些解释:我正在写这本书,关于特定领域的某个算法子集。我已经为自己设定了一个非常随意的目标,即以可读性和其他方式为代价,为我的所有算法提供最有效(时间和空间)的实现。这部分是我(一般)问题的本质。

回答:我希望我能够从最快的速度到最常见的感觉(所有这些都是先验的,即没有测试):

  1. 在全局对象中存储outvalues(我会假设像outvals [2]?)或
  2. 将outvalues传递为函数中的params(foo(int in,int * out1,int * out2))或
  3. 返回包含两个outvals的结构,或
  4. (3)仅当值与语义相关时。
  5. 这有意义吗?如果是这样的话,我认为Jason的回答是最接近的,即使他们都提供了一些“谜题”。罗伯特很好,但此时语义不是我所追求的(尽管他的建议得到了适当的注意)

    谢谢大家。

11 个答案:

答案 0 :(得分:7)

这两种方式都是有效的,但是我会考虑语义(struct vs参数引用)来决定最好的向程序员传达你的意图。< / p>

如果您要返回的值紧密耦合,则可以将它们作为结构返回。但是,如果您只是创建仿造机制来一起返回值(作为结构),那么您应该使用参数引用(即传递变量的地址)将值返回给调用功能

答案 1 :(得分:5)

正如尼尔所说,你需要自己判断。

为避免传递任何内容的成本,请使用全局。接下来最好的是指针/引用传递的单个结构。之后是单独的指针/参考参数。

但是,如果您必须将数据打包到结构中,然后在通话后将其读回,则最好传递单个参数。

如果您不确定,只需使用两种方法编写一些快速测试代码,每次执行几十万次,然后计算它们以查看哪种方法最佳。

答案 2 :(得分:3)

您已经描述了两种可能的解决方案和您感知到的性能约束。你离开这里的地方真的取决于你 - 我们没有足够的信息来做出明智的判断。

答案 3 :(得分:3)

最简单的阅读应该是在函数中传递地址,它也应该快,pops和push很便宜:

void somefunction (int inval1, int inval2, int *outval1, int *outval2) {
   int x = inval1;
   int y = inval2;
// do some processing
   *outval1 = x;
   *outval2 = y;
   return;
}

答案 4 :(得分:1)

我能想到的最快的Q&amp; D方式是在全局对象上传递值,这样就可以跳过堆栈操作,只要记住它不是线程安全的。

答案 5 :(得分:1)

我认为当你返回一个struct指针时,你可能需要为此手动找到一些内存。参数列表中的地址在堆栈上分配,这样更快。

答案 6 :(得分:1)

请记住,有时通过值传递参数和返回时更新(或在堆栈上创建本地副本)比通过引用更快...这对于小结构或少量参数和大量访问非常明显。 / p>

答案 7 :(得分:0)

我会将地址传递给结构体。如果要返回的信息不复杂,那么只需将地址传递给值也可以。

就个人而言,它实际上归结为界面的混乱程度。

void SomeFunction( ReturnStruct* myReturnVals )
{
  // Fill in the values
}   

// Do some stuff    
ReturnStruct returnVals;
SomeFunction( &returnVals);    
// Do more stuff

答案 8 :(得分:0)

这很大程度上取决于您的体系结构,以及您期望(或可能拥有)内联函数。我首先以最简单的方式编写代码,然后担心速度,如果它显示为代码的昂贵部分。

答案 9 :(得分:0)

在任何一种情况下,您都要传递引用,因此性能应该相似。如果函数有可能永远不会实际返回值,则可以使用“return a struct”选项来避免malloc的开销,因为您只需返回null。

我个人的偏好是返回一个动态分配的(malloc'd)结构。我避免使用函数参数进行输出,因为我认为它会使代码更加混乱,并且在长期内难以维护。

答案 10 :(得分:-1)

返回结构的本地副本是不好的,因为如果结构在函数内被声明为非静态,则退出函数后它将变为null和void。

对于所有建议引用的人,OP确实说“C”,C没有它们(参考文献)。

耶和华的羽毛,我能明天醒来,而不必在电视上看到关于翻牌王的事吗?