简体   繁体   English

从 C function 返回多个值

[英]Returning multiple values from a C function

Important : Please see this very much related question: Return multiple values in C++ .重要提示:请参阅这个非常相关的问题: 在 C++ 中返回多个值

I'm after how to do the same thing in ANSI C?我在寻找如何在 ANSI C 中做同样的事情? Would you use a struct or pass the addresses of the params in the function?您会使用结构还是传递 function 中的参数地址? I'm after extremely efficient (fast) code (time and space), even at the cost of readability.我追求极其高效(快速)的代码(时间和空间),即使以可读性为代价。

EDIT : Thanks for all the answers.编辑:感谢所有的答案。 Ok, I think I owe some explanation: I'm writing this book about a certain subset of algorithms for a particular domain.好吧,我想我应该解释一下:我正在写这本书,内容是关于特定领域的某个算法子集。 I have set myself the quite arbitrary goal of making the most efficient (time and space) implementations for all my algos to put up on the web, at the cost of readability and other stuff.我为自己设定了一个相当武断的目标,即为我的所有算法在 web 上进行最有效的(时间和空间)实现,但以牺牲可读性和其他东西为代价。 That is in part the nature of my (general) question.这部分是我(一般)问题的性质。

Answer : I hope I get this straight, from (possibly) fastest to more common-sensical (all of this a priori, ie without testing):回答:我希望我能直截了当,从(可能)最快到更常识(所有这些都是先验的,即未经测试):

  1. Store outvalues in global object (I would assume something like outvals[2]?), or将超出值存储在全局 object 中(我会假设类似于 outvals[2]?),或者
  2. Pass outvalues as params in the function (foo(int in, int *out1, int *out2)), or在 function (foo(int in, int *out1, int *out2)) 中将输出值作为参数传递,或
  3. return a struct with both outvals, or返回一个包含两个值的结构,或
  4. (3) only if the values are semantically related. (3) 仅当值在语义上相关时。

Does this make sense?这有意义吗? If so, I think Jason's response is the closest, even though they all provide some piece of the "puzzle".如果是这样,我认为 Jason 的回应是最接近的,尽管它们都提供了一些“谜题”。 Robert's is fine, but at this time semantics is not what I'm after (although his advice is duly noted).罗伯特的很好,但此时语义不是我所追求的(尽管他的建议得到了适当的注意)。

Both ways are valid, certianly, but I would would consider the semantics (struct vs parameter reference) to decide which way best communicates you intentions to the programmer. 这两种方式都是有效的,但是我会考虑语义 (struct vs parameter reference)来决定哪种方式最能将你的意图传达给程序员。

If the values you are returning are tightly coupled , then it is okay to return them as a structure. 如果要返回的值紧密耦合 ,则可以将它们作为结构返回。 But, if you are simply creating artificial mechanism to return values together (as a struct), then you should use a parameter reference (ie pass the address of the variables) to return the values back to the calling function. 但是,如果您只是创建人工机制将值一起返回(作为结构),那么您应该使用参数引用(即传递变量的地址)将值返回给调用函数。

As Neil says, you need to judge it for yourself. 正如尼尔所说,你需要自己判断。

To avoid the cost of passing anything, use a global. 为了避免传递任何东西的成本,请使用全局。 Next best is a single structure passed by pointer/reference. 接下来最好的是指针/引用传递的单个结构。 After that are individual pointer/reference params. 之后是单独的指针/参考参数。

However, if you have to pack data into the structure and then read it back out after the call, you may be better off passing individual parameters. 但是,如果您必须将数据打包到结构中,然后在调用后将其读回,则最好传递单个参数。

If you're not sure, just write a bit of quick test code using both approaches, execute each a few hundred thousand times, and time them to see which is best. 如果您不确定,只需使用两种方法编写一些快速测试代码,每次执行几十万次,并计算它们以查看哪种方法最佳。

You have described the two possible solutions and your perceived performance constraint. 您已经描述了两种可能的解决方案和您感知到的性能约束。 Where you go from here is really up to you - we don't have enough information to make an informed judgement. 你离开这里的地方真的取决于你 - 我们没有足够的信息来做出明智的判断。

Easiest to read should be passed addresses in the function, and it should be fast also, pops and pushes are cheap: 最容易阅读的应该是在函数中传递地址,它应该也很快,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;
}

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

I think that when you return a struct pointer, you probably need to manually find some memory for that. 我认为当你返回一个struct指针时,你可能需要手动为它找到一些内存。 Addresses in parameter list are allocated on the stack, which is way faster. 参数列表中的地址在堆栈上分配,这样更快。

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

I would pass the address to a struct. 我会将地址传递给结构。 If the information to be returned isn't complex, then just passing in the addresses to the values would work too. 如果要返回的信息不复杂,那么只需将地址传递给值也可以。

Personally, it really comes down to how messy the interface would be. 就个人而言,它实际上归结为界面的混乱程度。

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

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

This depends massively on your architecture, and also if you expect (or can have) the function inlined. 这在很大程度上取决于您的体系结构,如果您期望(或可以拥有)内联函数。 I'd first write the code in the simplest way, and then worry about speed if that shows up as an expensive part of your code. 我首先以最简单的方式编写代码,然后担心速度,如果它显示为代码的昂贵部分。

In either case, you're passing references, so performance should be similar. 在任何一种情况下,您都要传递引用,因此性能应该类似。 If there is a chance that the function never actually returns a value, you could avoid the cost of the malloc with the "return a struct" option since you'd simply return null. 如果函数有可能永远不会实际返回值,则可以通过“return a struct”选项来避免malloc的开销,因为您只需返回null。

My personal preference is to return a dynamically allocated (malloc'd) struct. 我个人的偏好是返回一个动态分配的(malloc'd)结构。 I avoid using function arguments for output because I think it makes code more confusing and less maintainable in the long-term. 我避免使用函数参数进行输出,因为我认为它会使代码更加混乱,并且在长期内难以维护。

Returning a local copy of the structure is bad because if the struct was declared as non-static inside the function, it becomes null and void once you exit the function. 返回结构的本地副本是不好的,因为如果结构在函数内声明为非静态,则退出函数后它将变为null和void。

And to all the folks suggesting references, well the OP did say "C," and C doesn't have them (references). 并且对于所有建议引用的人,OP确实说“C”,而C没有它们(参考文献)。

And sweet feathery Jesus, can I wake up tomorrow and not have to see anything about the King of Flop on TV? 还有甜美的羽毛耶稣,我明天可以醒来,而不必在电视上看到任何关于翻牌王的事吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM