在结构中初始化typedef数组

时间:2018-12-21 13:46:09

标签: c arrays struct typedef

我正在制作Camera结构。该结构使用vec3定义的typedef float vec3[3]

要初始化vec3,请执行vec3 vector = {0.,0.,0.};

我的Cameras结构是这样的:

typedef struct Cameras {
    vec3 eye;
    vec3 target
} Camera;

但是当我这样做时:

Camera cam;
cam.eye = { .5, 1., 0. };

它崩溃了,编译器告诉我:expression must be modifiable

我认为指针出错,但没有,将vec3 eye替换为vec3 * eyecam->eye = {.5,1.,0.}并没有任何改变。

我是用错误的方式创建结构还是真的很常见的问题C,我只是盲目?

在这里,我的目标不仅是初始化数组,而且还要在创建后访问数据并修改/传递函数。

3 个答案:

答案 0 :(得分:6)

这是因为在定义行cam之后,后续的“赋值”不再进行初始化

初始化一个实例,必须将“赋值”放置在定义它的位置:

Camera cam = { {.5, 1., 0.} };

或指定成员:

Camera cam = { .eye = {.5, 1., 0.} };

请注意,由于未为cam.target指定任何初始值,这也会自动将其初始化为零。

答案 1 :(得分:1)

您得到的错误是显而易见的,vec3的类型为float [3]-数组类型,您当然不能“分配”给数组类型。

您可以使用iBug在另一个答案中提到的初始化。但是,只需一个小的 trick ,您就可以使用分配。这将需要使用指针和compound literal

您需要将typedef更改为vec3

 typedef float* vec3;

以使其为float *,然后,您可以使用复合文字来分配值,例如

cam.eye = (float [3]){ .5, 1., 0. };
cam.target = (float [3]){ .45, 2.5, 0.9 }; // just some other values.

使用这种方法的主要好处是,您不仅限于“初始化”,还可以随时执行分配。

PS -Compound literals are modifiable,因此您不会失去任何操作能力。

P.P.S。

引用C11,第6.5.2.5节/ P12

"/tmp/fileXXXXXX" 
 (char []){"/tmp/fileXXXXXX"} 
 (const char []){"/tmp/fileXXXXXX"} 
     

第一个始终具有静态存储期限   并且具有char类型数组,但不必修改;最后两个   当它们出现在人体中时,具有自动存储时间   功能,并且这两个中的第一个是可修改的。

答案 2 :(得分:0)

我个人更喜欢更具“描述性”的初始化-我希望指定成员-该代码对于人类来说更易于阅读。

//