最好将struct或指针传递给struct?

时间:2015-06-10 13:43:47

标签: c struct embedded

我有一个数据结构,将在函数中读取。

我希望最小的内存,代码大小和速度足迹。我正在研究AVR。

typedef struct {
    uint16_t clu;
    uint16_t num;
    uint32_t cur_rel;
} FSAVEPOS;

现在,一个将文件位置存储到结构中的函数:

// Approach 1
FSAVEPOS save_pos(const FFILE* file); // return value

// Approach 2
void save_pos(const FFILE* file, FSAVEPOS* pos); // modify reference

一个反转它的函数(FFILE对象被修改):

// Approach 1
void restore_pos(FFILE* file, const FSAVEPOS pos); // pass by value

// Approach 2
void restore_pos(FFILE* file, const FSAVEPOS* pos); // pass by reference

你认为什么是最好的主意?

2 个答案:

答案 0 :(得分:2)

如果您尝试最小化内存占用,那么使用指针可以更好地传递比指针大得多的struct类型。显着更小的数据更好地通过值传递。如果指针和数据的大小差不多,则无关紧要。

假设你在AVR32上,你的指针将是32位,结构是64位(加上任何填充)。

这表明你最好通过指针/引用传递。但是,结构并不是特别大,其他考虑因素可能占主导地位 - 对于struct类型来说,它并不是很重要,因为它并不是特别大。您需要确定相关数量(内存使用情况,代码大小,速度等)。

所以我建议最好的想法是测量 - 这些东西会受到主机架构,编译器设置,编译器实现质量等的影响。

虽然您没有问过,但较大的类型(如uint32_t)往往比较小的类型(如uint16_t)具有更大的对齐要求。这样做的结果是对结构的成员进行排序的相当常见的指导原则,因此较大的类型首先出现在内存中。在您的情况下,这可能并不重要(可以肯定16位类型将与16位边界对齐,32位类型与32位边界对齐,因此很可能在您的情况下不会有填充案件)。但是,如果您有三个uint16_t成员而不是两个成员,那么最好先订购一些成员,这样uint32_t成员就是第一位。换句话说,而不是

typedef struct
{
    uint16_t a,b,c;
    uint32_t d;
} SOME_TYPE;

你最好使用不同的订单。

typedef struct
{
    uint32_t d;
    uint16_t a,b,c;
} SOME_TYPE;

答案 1 :(得分:1)

在第一种情况下,当您在C中返回结构时,如果它适合或通过引用和修改后的AFAIK隐式传递,它通常会返回到寄存器中。因此,在最好的情况下,它会更好,在最坏的情况下,它与第二种方法相同。

在第二种情况下,它取决于指针的大小和结构的大小等。在这种情况下,没有测量就很难说什么。但是,对于那个大小的结构,它可能会有很大的不同。

但是,您应该考虑与API的其余部分保持一致,并且如果您无法执行操作(如果操作可能失败),则应该让系统通知错误。

相关问题