我正在制作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 * eye
和cam->eye = {.5,1.,0.}
并没有任何改变。
我是用错误的方式创建结构还是真的很常见的问题C,我只是盲目?
在这里,我的目标不仅是初始化数组,而且还要在创建后访问数据并修改/传递函数。
答案 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)
我个人更喜欢更具“描述性”的初始化-我希望指定成员-该代码对于人类来说更易于阅读。
//