在C中通过值传递结构有什么坏处,而不是传递指针呢?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (16)

在C中传递结构的价值有什么缺点,而不是传递一个指针?

如果结构很大,显然有复制大量数据的性能方面,但对于较小的结构,它应该基本上与将多个值传递给函数相同。

用作返回值可能更有趣。C只有函数的单个返回值,但你通常需要几个。所以一个简单的解决方案是把它们放在一个结构体中并返回它。

有没有任何理由支持或反对?

由于这里可能并不是很明显,所以我会举一个简单的例子。

如果你用C编程,你迟早会开始编写看起来像这样的函数:

void examine_data(const char *ptr, size_t len)
{
    ...
}

char *p = ...;
size_t l = ...;
examine_data(p, l);

这不是问题。唯一的问题是,你必须同意你的同事参数的顺序应该是这样的,所以你在所有函数中使用相同的约定。

但是当你想要返回相同类型的信息时会发生什么?你通常会得到这样的东西:

char *get_data(size_t *len);
{
    ...
    *len = ...datalen...;
    return ...data...;
}
size_t len;
char *p = get_data(&len);

这工作正常,但更有问题。返回值是一个返回值,除了在此实现中它不是。从上面没有办法告诉我们函数get_data不允许查看len指向的内容。并且没有任何东西让编译器检查一个值是否通过该指针实际返回。那么下个月,当别人修改代码而没有正确理解代码时(因为他没有阅读文档?)它会在没有任何人注意的情况下被破坏,或者随机开始崩溃。

所以,我提出的解决方案是简单的结构

struct blob { char *ptr; size_t len; }

这些例子可以像这样重写:

void examine_data(const struct blob data)
{
    ... use data.tr and data.len ...
}

struct blob = { .ptr = ..., .len = ... };
examine_data(blob);

struct blob get_data(void);
{
    ...
    return (struct blob){ .ptr = ...data..., .len = ...len... };
}
struct blob data = get_data();

出于某种原因,我认为大多数人会本能地使examine_data采取一个指向结构blob的指针,但我不明白为什么。它仍然得到一个指针和一个整数,它们更加清晰,它们一起。而在get_data的情况下,不可能像我之前描述的那样混乱,因为长度没有输入值,并且必须有返回的长度。

提问于
用户回答回答于

没有提到的原因之一是没有提到这一点,这可能会导致二进制兼容性问题。

根据使用的编译器,结构可以通过堆栈或寄存器传递,具体取决于编译器选项/实现

请参阅:http : //gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html

-fpcc-结构回报 -freg-结构回报

如果两个编译器不同意,事情可能会炸毁。不用说,不这样做的主要原因是堆栈消耗和性能原因。

用户回答回答于

对于小型结构(例如点,矩形)而​​言,通过价值是完全可以接受的。但是,除了速度之外,还有一个原因是为什么你应该小心地按照价值传递/返回大型结构:堆栈空间。

很多C编程都适用于嵌入式系统,其中内存非常重要,堆栈大小可能以KB或甚至Bytes为单位进行测量。

如果我看到一个似乎具有过多堆栈使用的应用程序,那么通过值传递的结构是我首先查找的事物之一。

扫码关注云+社区