【问题标题】:Is there any case for which returning a structure directly is good practice?在任何情况下直接返回结构是好的做法吗?
【发布时间】:2011-09-26 03:52:39
【问题描述】:

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

什么时候直接返回结构是个好习惯?

【问题讨论】:

标签: c coding-style


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      • “函数式编程”风格代码。传递了很多东西,并且有指针会使代码复杂化很多(如果您需要开始使用 malloc+free,这甚至不算数)

      • 小型结构,例如

        struct Point{ int x, y; };
        

        不值得通过引用传递东西的麻烦。


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

      【讨论】:

      • C 中的“传递引用”是什么意思?
      • @Chris:这意味着将任何“引用”传递给标准英语意义上的数据,例如一个指针,或者一个全局池的索引,或者类似的......
      • @Chris Lutz:这个术语并不是真正的 C 特定的。当您通过设置另一个变量或将其传递给函数来传递“普通”变量(例如,int)时,对第二个变量的任何更改不会反映在原始变量中,因为它实际上正在处理副本。另一方面,如果您在周围传递一个指针(也称为引用),任何更改也会反映在原始变量上。
      【解决方案4】:

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

      但这些考虑仅适用于特定情况:THIS 部分 THIS program on THIS architecture。

      对于编写C程序的水平,你应该使用更容易阅读的。

      【讨论】:

        【解决方案5】:

        如果你想让你的函数没有副作用,直接返回一个结构会有所帮助,因为它实际上是按值传递的。是不是更有效率?不,通过引用传递更快。但是没有副作用可以真正简化线程的工作(众所周知的困难任务)。

        【讨论】:

        • 嗯.. 我会说按值传递结构会对许多多线程应用程序产生负面影响(mod small structs,正如其他海报已经指出的那样)。 malloced 指针可以轻松、快速且安全地排队到其他线程。返回到自动变量的结构必须保持完整,直到目标线程完成它,或者队列必须与结构一样宽,因此必须在将结构复制到队列中的整个时间内锁定.
        【解决方案6】:

        在某些情况下,按值返回结构是相反的:

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

        2) 包含可变长度数据缓冲区的结构,其中结构已调整大小以适应数据的绝对最大大小,但平均数据大小要小得多,例如。一个网络缓冲区结构,其末尾有一个 'dataLen' int 和一个 'char data[65536]'。

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

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

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

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

        4) 不同def的结构在哪里。将存储在任何数组/列表/队列/堆栈/whateverContainer 中。

        我怀疑我被 c++ 和其他 OO 语言所破坏,以至于我倾向于 malloc/new 几乎所有不能以本机类型存储的东西

        Rgds, 马丁

        【讨论】:

          猜你喜欢
          • 2020-11-13
          • 1970-01-01
          • 2011-08-11
          • 2010-10-07
          • 2022-11-19
          • 2017-03-31
          • 2014-08-15
          相关资源
          最近更新 更多