3

例如,给定一个结构S:给定一个指向结构体的指针,我可以在一行中分配一个聚合初始化程序的结果吗?

typedef struct { 
    int a, b; 
} S; 

...和这需要一个指向S,一种方法我可以指定它的聚集体初始化的值都在一个行?这是我现有的解决方案,它使用一个临时的:

void init_s(S* s) { 
    S temp = { 1, 2 }; 
    *s = temp; 
} 

我正在使用C11。


对于非常罕见的超级学究谁不明白我的问题,因为在某种程度上“聚合初始化”不会在这里适用,因为LHS没有宣布一个新的对象,我的意思是“聚集物与花括号和东西的初始化类似的语法“。

+1

是:'* S =(S){1,2};'见C11 n1570,§6.5.2.5 *化合物文字*,第10段:例3:'drawline((struct point){。x = 1,.y = 1},(struct point){。x = 3,.y = 4});' –

+0

@IwillnotexistIdonotexist - 它[作品](https://godbolt.org/g/SFhL3z),谢谢!足够好的答案:) – BeeOnRope

+0

'* s = ...'不是一个初始化程序。由于's'已经被声明,你根本不能使用一个初始化器。上面的代码不会**编译。 – Olaf

回答

5

是的,则可以使用compound literals语法:

#include <stdio.h> 

typedef struct { 
    int a, b; 
} S; 

int main(void) { 
    S s; 
    S *p = &s; 

    *p = (S){1,2}; 

    printf("%d %d\n", p->a, p->b); 
    return 0; 
} 

Demo

+0

如果复合文字不打算修改,最好是“静态常量”。否则可能会涉及两个复制操作(取决于编译器的智能程度)。 – Olaf

+0

至少对于这个玩具的例子来说,clang和gcc是正确的,为复合文字赋值和明确指定字段的版本生成相同的[code](https://godbolt.org/g/HzNhgP)(和它们都足够聪明,可以将两个32位常量合并为一个64位常量并一次赋值)。如果'a'和'b'是参数,'icc'会生成相同的代码,但在常量情况下,它会以不同的方式生成:在它的'.rodata'节创建一个常量(S){1,2}对象负载。对于大量常量重复使用这可能是明智的,但在这里似乎是错误的。 – BeeOnRope

相关问题