代码之家  ›  专栏  ›  技术社区  ›  Dervin Thunk

从C函数返回多个值

  •  6
  • Dervin Thunk  · 技术社区  · 15 年前

    重要的 :请看这个非常相关的问题: Return multiple values in C++ .

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

    编辑 :谢谢你的回答。好吧,我想我应该得到一些解释:我写这本书是关于一个特定领域的特定算法子集的。我已经为自己设定了一个非常任意的目标,那就是以可读性和其他东西为代价,为我所有的算法在网络上实现最有效的(时间和空间)实现。这在一定程度上是我(一般)问题的性质。

    回答 :我希望我能直截了当地说出来,从(可能)最快到更普通的感官(所有这些都是先验的,即没有测试的):

    1. 在全局对象中存储outValues(我假设outVals[2]?)或
    2. 在函数(foo(int-in,int*out1,int*out2))中将outvalues作为参数传递,或者
    3. 返回包含两个outvals的结构,或者
    4. (3)仅当这些值在语义上相关时。

    这有道理吗?如果是这样的话,我认为杰森的反应是最接近的,尽管他们都提供了一些“谜题”。罗伯特的建议很好,但此时语义不是我想要的(尽管他的建议被适当地指出了)。

    谢谢大家。

    11 回复  |  直到 6 年前
        1
  •  5
  •   Robert Cartaino    15 年前

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

    要避免传递任何内容的成本,请使用全局。其次,最好是由指针/引用传递的单个结构。之后是单独的指针/引用参数。

    但是,如果必须将数据打包到结构中,然后在调用后将其读回,那么最好不要传递单个参数。

    如果您不确定,只需使用这两种方法编写一点快速测试代码,分别执行几十万次,然后计时看哪种方法最好。

        2
  •  7
  •   halfer Rajnish Kumar    6 年前

    两种方法都是有效的,但我会的。 考虑语义 (结构与参数引用)决定哪种方式最好 传达你的意图 给程序员。

    如果返回的值 紧密耦合 ,然后可以将它们作为结构返回。但是,如果你只是在创造 人工机制 若要一起返回值(作为结构),则应使用参数引用(即传递变量的地址)将值返回给调用函数。

        3
  •  3
  •   anon    15 年前

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

        4
  •  3
  •   KevinDTimm    15 年前

    最容易读取的应该是在函数中传递的地址,它也应该很快,pop和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;
    }
    
        5
  •  1
  •   Shay Erlichmen    15 年前

    我能想到的最快的Q&D方法是传递全局对象的值,这种方法跳过堆栈操作,只需记住它不会是线程安全的。

        6
  •  1
  •   Tadeusz A. Kadłubowski    15 年前

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

        7
  •  1
  •   fortran    15 年前

    请记住,有时按值传递参数和返回时更新(或在堆栈上创建本地副本)比按引用传递参数更快…这在结构小、参数少、访问量大的情况下非常明显。

        8
  •  0
  •   DaveR    15 年前

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

        9
  •  0
  •   rahularyansharma    15 年前

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

    就个人而言,这实际上取决于界面有多混乱。

    void SomeFunction( ReturnStruct* myReturnVals )
    {
      // Fill in the values
    }   
    
    // Do some stuff    
    ReturnStruct returnVals;
    SomeFunction( &returnVals);    
    // Do more stuff
    
        10
  •  0
  •   Cory Engebretson    15 年前

    在这两种情况下,都是传递引用,所以性能应该类似。如果函数实际上从未返回值,那么可以使用“返回结构”选项避免malloc的开销,因为您只返回空值。

    我的个人偏好是返回一个动态分配(malloc'd)结构。我避免在输出中使用函数参数,因为我认为从长远来看,它会使代码更混乱,更不易维护。

        11
  •  -1
  •   xcramps    15 年前

    返回结构的本地副本是错误的,因为如果该结构在函数内声明为非静态的,则一旦退出该函数,它将变为空。

    对于所有建议引用的人来说,操作系统确实会说“c”,而c没有它们(引用)。

    还有可爱的羽毛耶稣,我能明天醒来而不必在电视上看到任何关于失败之王的事情吗?