C:何时按值返回或传递引用

时间:2015-03-11 13:34:56

标签: c pointers reference return-value

虽然这个主题已被多次讨论过,但到目前为止我还没有找到任何令人满意的答案。何时通过返回从函数返回数据或通过引用更改地址数据?经典的答案是在变量变大时将变量作为函数的引用传递(以避免堆栈复制)。这看起来像结构或数组。但是,从函数返回指针并不罕见。实际上有些函数从C库到确切的东西。例如:

char *strcat(char *dst, const char *src);

即使出现错误,也始终返回指向目标的指针。在这种情况下,我们可以使用传递的变量并保留返回值(就像大多数一样)。

在看结构时,我发现同样的事情正在发生。当函数需要在变量初始化中使用时,我经常返回指针。

char *p = func(int i, const char *s);

然后有一个论点,堆栈应对变量是昂贵的,所以使用指针代替。但正如前面提到的here,一些编译器能够自己决定(假设这也适用于C)。是否有一般规则,或者至少有一些不成文的惯例何时使用其中一种?我认为性能高于设计。

2 个答案:

答案 0 :(得分:13)

首先确定哪种方法在逻辑级别最有意义,而不管您认为性能影响可能是什么。如果按值返回struct,则最清楚地传达代码的 intent ,然后执行此操作。

这不再是20世纪80年代了。从那时起,编译器变得更加智能,并且在优化代码方面做得非常好,特别是以清晰,直接的方式编写的代码。类似地,参数传递和值返回约定也变得相当复杂。简单的基于堆栈的模型并没有真正反映现代硬件的现实。

如果生成的应用程序不符合您的性能标准,则通过分析器运行它以找到瓶颈。如果事实证明按值返回struct导致问题,那么然后您可以尝试通过引用函数来传递。

除非您在高度受限的嵌入式环境中工作,否则您实际上不必计算每个字节和CPU周期。你不想浪费不必要的东西,但同样的道理,除非a)你有非常严格的性能要求,并且你是亲密的,否则你不想在低层次上如何工作。熟悉特定平台的详细信息(这意味着您不仅要了解平台的内部和外部函数调用约定,还要了解编译器如何使用这些约定)。否则,你只是在猜测。让编译器为您努力工作。这就是它的用途。

答案 1 :(得分:-2)

经验法则:

  1. 如果sizeof(return type)大于sizeof(int),您应该通过指针传递它以避免复制开销。这是一个性能问题。取消引用指针会有一些惩罚,因此这条规则有一些例外。
  2. 如果返回类型很复杂(包含指针成员),则通过指针传递它。例如,将本地返回值复制到堆栈不会复制动态内存。
  3. 如果希望函数分配内存,则应返回指向新分配内存的指针。它被称为 factory 设计模式。
  4. 如果你想从一个函数返回多个东西 - 按值返回一个,并用指针传递其余的东西。
  5. 如果您有一个既输入又输出的复杂/大数据类型,请通过指针传递它。