C 是否存在直接返回结构是良好做法的情况?

C 是否存在直接返回结构是良好做法的情况?,c,coding-style,C,Coding Style,IMO所有直接返回结构的代码都可以修改为返回指向结构的指针 什么时候直接返回结构是一种好的做法?如何修改?返回指向函数中结构的静态实例的指针,从而使函数不可重入;或者通过返回一个指向堆分配结构的指针,调用者必须确保释放并适当地释放该结构?在一般情况下,我认为返回一个结构是很好的做法。 < P>如果你试图使你的函数无副作用,直接返回一个结构会有帮助,因为它会有效地通过值。效率更高吗?不,通过引用传递更快。但是没有副作用可以真正简化线程的工作(这是一项众所周知的困难任务)。返回完整的结构而不是指针的

IMO所有直接返回结构的代码都可以修改为返回指向结构的指针


什么时候直接返回结构是一种好的做法?

如何修改?返回指向函数中结构的静态实例的指针,从而使函数不可重入;或者通过返回一个指向堆分配结构的指针,调用者必须确保释放并适当地释放该结构?在一般情况下,我认为返回一个结构是很好的做法。

< P>如果你试图使你的函数无副作用,直接返回一个结构会有帮助,因为它会有效地通过值。效率更高吗?不,通过引用传递更快。但是没有副作用可以真正简化线程的工作(这是一项众所周知的困难任务)。

返回完整的结构而不是指针的最大优点是不必弄乱指针。通过避免指针固有的风险,特别是在分配和释放自己的内存时,编码和调试都可以大大简化


在许多情况下,直接传递结构的优点大于将整个结构复制到堆栈的缺点(时间/内存)。除非您知道优化是必要的,否则没有理由不采取更简单的方法。

我认为以下情况是我最常选择的直接传递结构方法:

  • “函数式编程”风格的代码。大量的东西被传递,并且有指针会使代码复杂化很多(如果你需要开始使用malloc+free,这还不算在内)

  • 小型结构,例如

    struct Point{ int x, y; };
    
    不值得费心通过引用来传递信息



最后,请不要忘记,传递值和传递引用实际上是非常不同的,因此某些类的程序将更适合一种风格,如果使用另一种风格,最终会看起来很难看。

这些其他答案都很好,但我认为missingno最接近于“回答问题”通过提到小结构。更具体地说,如果结构本身只有几个机器字长,那么“空间”反对和“时间”反对都被克服了。如果指针是一个单词,而结构是两个单词,那么结构复制操作比指针复制慢多少?在缓存架构上,我怀疑答案是“无”。至于空间,堆栈上的2个字<堆栈上的1个字+堆上的2个字(+开销)

但是这些注意事项只适用于特定的情况:这个程序在这个体系结构上的这个部分


对于编写C程序的级别,您应该使用更容易阅读的版本。

在少数情况下,禁止按值返回结构:

1) 一种库函数,返回“令牌”数据,稍后在其他调用(如文件或套接字流描述符)中重复使用。返回完整的结构将破坏库的封装

2) 包含可变长度数据缓冲区的结构,其中结构的大小已调整为容纳数据的绝对最大大小,但平均数据大小要小得多,例如,在其末端有“dataLen”int和“char data[65536]”的网络缓冲区结构

3) 任何类型的大型结构,其中复制数据的成本变得很高,例如:

a) 当必须通过多个函数调用返回结构时-相同数据的多次复制

b) 当结构随后排队到其他线程范围的队列时,意味着在复制入/复制出过程中锁定时间更长,从而增加争用的机会。结构的大小会同时影响生产者线程堆栈和消费者线程堆栈

c) 结构经常在层之间移动,例如协议栈

4) 其中,定义不同的结构。将存储在任何数组/列表/队列/堆栈/whateverContainer中

<>我怀疑我被C++和其他OO语言破坏了,我倾向于MaloC/NoD,几乎不能存储在原生类型< /P>中的任何东西。 Rgds,
马丁

dupe?“通过引用传递”在C中是什么意思?@Chris:它意味着传递任何“引用”到标准英文单词意义上的数据块的东西,例如指针,或指向全局池的索引,或类似的东西。@Chris Lutz:这个术语实际上并不特定于C。当您通过设置另一个变量或将其传递给函数来传递“普通”变量(例如int)时,对第二个变量的任何更改都不会反映在原始变量中,因为它实际上是在处理副本。另一方面,如果在周围传递指针(也称为引用),任何更改也会反映回原始变量。Hmm。。我会说,按值传递结构会对许多多线程应用程序产生负面影响(mod small structs,正如其他海报所指出的)。malloced指针可以轻松、快速、安全地排队到其他线程。返回到自动变量的结构必须保持完整,直到目标线程完成它,或者队列必须与结构一样宽,因此必须在将结构复制到队列中所花费的整个时间内锁定。