在 ANSI C 中,我能否在一行上返回一个已初始化的结构体?

24

我只是想知道我是否可以做类似的事情...

typedef struct Result{
  int low, high, sum;
} Result;

Result test(){
  return {.low = 0, .high = 100, .sum = 150};
}

我知道那不是正确的方式,但我能这样做吗?或者我需要创建一个本地变量来接收值,然后再返回它吗?

2个回答

41
你可以通过使用一个复合字面量来实现此目的:
Result test(void)
{
    return (Result) {.low = 0, .high = 100, .sum = 150};
}

(){} 是复合字面量运算符,复合字面量是 c99 引入的一个特性。


这种方法会导致编译器分配内存来保存一个“Result”结构体,其中字段最初被复制到该结构体中,然后再次复制到调用者的“Result”结构体实例中。这两个副本和“Result”结构体的分配都是真正的RAM和CPU周期浪费者。 - user3629249
2
@user3629249:但是这些可以进行优化,并且是ABI特定的。在Linux/x86-64上,一个两个字段的struct通常会在两个寄存器中返回。 - Basile Starynkevitch
优化编译器会尽可能将结构体放入单个寄存器中(在x64上,任何适合8字节的都会被写入单个寄存器),当然,如果可能的话,它还会完全优化整个结果 - vgru
1
如果使用简单的结构体,您可以避免编写字段名称:return (Result){0, 100, 150}; - tleb
所以,由于括号的存在,这是否在技术上算是类型转换呢?顺便说一下,非常感谢你。 - Palbitt

-5
struct Result
{
    int low;
    int high;
    int sum;
};

then to create an instance of the struct

struct Result myResult;

Regarding your question...

prototype for the test function

void test( struct Result *myResult );

invoke the function by:

test( &myResult );

the test function:

void test( struct Result *argResult )
{
    argResult->low  = 0;
    argResult->high = 100;
    argResult->sum  = 150;
}

3
"Typedef结构体已经过时了???此外,'test(struct Result&myResult)' - 自从什么时候成为C语言中“调用函数”的一种方式?" - AnT stands with Russia
没错,我会把这一行改成调用该函数。 - user3629249
我找不到有关typedef结构体被弃用的原始参考资料,因此我删除了该语句。 - user3629249

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