指向结构体的指针还是结构体本身?

6

考虑以下代码:

struct s { /* ... */ };

void f(struct s x) { /* ... */) /* (1) */
/* or */
void f(const struct s *x) { /* ... */ } /* (2) */

struct s的大小较大时,我们应该在什么情况下选择第一种形式?


我个人的做法是在结构体变得很大时只传递指针,因为与传递整个大型结构相比,仅传递指针速度要快得多。 - Keith Miller
你没有说“体面”是什么意思。它可能意味着任何东西。像1024字节这样的漂亮的整数,算是体面吗?此外,在这个网站上询问偏好而不是绝对值是被反对的。 - Mr Lister
3个回答

6

你是在问哪个更好吗?

这取决于你想要做什么 - 用指针的第二种形式会更有效率。但如果你只是想将一个值传递给f,而不必担心副作用,那么你可能会选择第一种形式 - 只要struct不太大。


第二种形式为什么更高效? - Mike
@Mike:因为你正在复制一个指针。如果该结构体的大小大于指针(几乎肯定是这种情况),那么你就需要做更多的工作。 - Ed S.
2
我也不确定你所说的副作用是什么。当然,const可以被强制转换,但你正在实现这个函数,对吧?所以,嗯...不要这样做或者去掉const。我更喜欢第二种形式。 - Ed S.

4
我建议阅读这篇文章
struct s足够大时,尤其是在递归函数中,应避免通过值传递它。
通过值传递结构体意味着在函数调用之前要将其复制。这导致执行速度较慢,内存利用率更高。此外,请注意,struct将在堆栈中分配,在某些系统中,堆栈大小非常有限。
除非您需要多个副本的结构体被函数修改且不希望这些修改仅在每个函数的作用域内可见,否则我建议在每种情况下都使用指针。

在这种情况下,使用联合体不是更合理吗? - NerdOfCode
@NerdOfCode 我不认为联合体会在那种情况下有所帮助。联合体本质上是可以有多个不同解释并占用最大可能解释空间的结构体。 - zakkak
因为每个元素只能同时存在一个元素。因此,可以提高内存利用率。 - NerdOfCode
我不确定我理解了。我们对结构本身一无所知。但是,即使我们假设联合体更合适,对于是按值传递还是按引用传递,同样的推理也适用。 - zakkak

-2

当您想让f获得x的副本而不是xconst指针时,请使用第一种形式。


2
为什么会是那样呢?能否提供一些陈述背后的推理呢?我认为 OP 理解这里正在进行复制,这不是问题。该对象是“const”,因此它不能被修改(除非你真的很想这样做),并且你避免了整个结构体的复制。 - Ed S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接