2017-03-26 123 views
1

我目前正在开发一个OpenGL应用程序。到目前为止,编程API时一切运行良好。C数组vs结构

对于通常的数据类型,我使用结构。例如:

struct vec3 { 
GLfloat x; 
GLfloat y; 
GLfloat z; 
} 

但现在我认为使用相同的数据类型作为简单数组,例如

typedef GLfloat vec3[3]; 

我真的很喜欢来处理类型,简单数组,因为它更容易访问他们,我甚至可以使用循环来修改它们的值(例如在GLfloat矩阵[16]中) 然而,我不喜欢C返回数组,所以我必须为操作提供存储空间 mat4_identity(mat4输出) 结构我可以很容易地说

mat4 m = mat4_identity() clean and nicely. 

我现在的问题是:哪一个是更好的性能明智的(当然具有例如许多verticies的时候,我只能认为重结构指针引用的+ acesses)哪一个,我应该在年底实际使用为我的OpenGL API。

+2

你有没有考虑过'struct vec3 {GLFloat vec3 [3]; }'? – chux

+0

@chux是的,但这似乎更像是一个奇怪的黑客/解决方法对我来说。理想的情况是,如果我可以使用结构体,但像数组一样访问它们(显然,当它们全都由具有相同数据类型的变量组成时)。不幸的是,这不起作用,因为我听说结构中有特殊的对齐或包装。 –

+0

'struct vec3 {union {struct {float x,y,z; }; float a [3]; };' – Joe

回答

2

如果您使用C11,您可以拥有两全其美!

union vec3 { 
     struct { 
      float x, y, z; 
     }; 
     float xyz[3]; 
}; 

然后你就可以访问它们任何一种方式:

printf("%f %f %f\n", vec.x, vec.y, vec.z); 
printf("%f %f %f\n", vec.xyz[0], vec.xyz[1], vec.xyz[2]); 

如果你不使用C11,你仍然可以做到这一点,但与三个组件的结构必须被命名为:

union vec3 { 
    struct { 
     float x, y, z; 
    } components; 
    float xyz[3]; 
} 

至于效率,数组保证是连续的(元素之间没有空白),而结构不是,所以可能是结构浪费了更多的内存。但是我认为考虑到现代计算机的内存数量,这是一个问题。

另请注意,虽然数组衰减为指针,但结构体不能保证这样做。除非结构符合寄存器(vec3可能不会),否则您应该传递指向它的指针而不是按值传递它。

+0

是否保证例如vec3.components.y == vec3.xyz [1]或者将allignment破坏所有内容? –

+0

pass by value can因为编译器可以更容易地证明不会发生混叠 – Joe

+0

@MuradBabayev因为我已经评论过您的问题,所以对齐不会破坏任何东西,因为编译器没有理由添加填充(对齐请求。从不大于对象的大小) – Joe