在C中按值传递结构是否有任何缺点,而不是传递指针?
如果结构很大,显然存在复制大量数据的性能方面,但对于较小的结构,它应该基本上与将多个值传递给函数相同.
当用作返回值时,它可能更有趣.C只有函数的单个返回值,但是你经常需要几个.所以一个简单的解决方案是将它们放在一个结构中并返回它.
是否有任何理由支持或反对这一点?
因为对于每个人来说,我在这里谈论的内容可能并不明显,所以我举一个简单的例子.
如果您使用C编程,您迟早会开始编写如下所示的函数:
void examine_data(const char *ptr, size_t len)
{
...
}
char *p = ...;
size_t l = ...;
examine_data(p, l);
Run Code Online (Sandbox Code Playgroud)
这不是问题.唯一的问题是你必须同意你的同事的参数顺序,所以你在所有功能中使用相同的约定.
但是当你想要返回相同类型的信息时会发生什么?你通常得到这样的东西:
char *get_data(size_t *len);
{
...
*len = ...datalen...;
return ...data...;
}
size_t len;
char *p = get_data(&len);
Run Code Online (Sandbox Code Playgroud)
这很好,但问题更多.返回值是返回值,但在此实现中它不是.从上面没有办法说明函数get_data不允许查看len指向的内容.并且没有任何东西可以使编译器检查实际通过该指针返回的值.那么下个月,当其他人修改代码时却没有正确理解它(因为他没有阅读文档?)它会在没有人注意的情况下破坏,或者随机开始崩溃.
所以,我提出的解决方案是简单的结构
struct blob { char *ptr; size_t len; }
Run Code Online (Sandbox Code Playgroud)
这些例子可以像这样重写:
void examine_data(const struct blob data)
{
... use data.tr and data.len ...
}
struct blob = { .ptr = ..., .len = ... };
examine_data(blob); …Run Code Online (Sandbox Code Playgroud) 结构可以通过值传递/返回,也可以通过C中的引用(通过指针)传递/返回.
普遍的共识似乎是,在大多数情况下,前者可以适用于没有惩罚的小结构.请参阅是否存在直接返回结构的良好做法?和是否有任何缺点由值用C传递结构,而不是传递指针?
从速度和清晰度的角度来看,避免取消引用可能是有益的.但什么算小?我想我们都同意这是一个小结构:
struct Point { int x, y; };
Run Code Online (Sandbox Code Playgroud)
我们可以通过相对有罪不罚的价值来传递:
struct Point sum(struct Point a, struct Point b) {
return struct Point { .x = a.x + b.x, .y = a.y + b.y };
}
Run Code Online (Sandbox Code Playgroud)
那个Linux task_struct是一个大型结构:
我们希望不惜一切代价避免使用堆栈(特别是那些8K内核模式堆栈!).但是什么是中等的?我假设小于寄存器的结构是好的.但那些呢?
typedef struct _mx_node_t mx_node_t;
typedef struct _mx_edge_t mx_edge_t;
struct _mx_edge_t {
char symbol;
size_t next;
};
struct _mx_node_t {
size_t id;
mx_edge_t edge[2];
int action;
};
Run Code Online (Sandbox Code Playgroud)
确定结构是否足够小以确定是否可以安全地通过值传递(缺少某些深度递归等情有可原的情况),最好的经验法则是什么?
最后请不要告诉我需要个人资料.当我太懒的时候,我要求使用启发式方法/它不值得进一步调查.
编辑:到目前为止,根据答案我有两个后续问题:
如果结构实际上小于指向它的指针怎么办? …