typedef union {
float flts[4];
struct {
GLfloat r;
GLfloat theta;
GLfloat phi;
GLfloat w;
};
struct {
GLfloat x;
GLfloat y;
GLfloat z;
GLfloat w;
};
} FltVector;
好的,所以我想我得到了如何使用它,(或者,这就是我看到它的使用方式)即。
FltVector fltVec1 = {{1.0f, 1.0f, 1.0f, 1.0f}};
float aaa = fltVec1.x;
etc.
但是我并没有真正意识到联盟宣布了多少存储量(4个花车?8个花车?12个花车?),怎么样?为什么?还有为什么在使用FltVector {{}}时会有两组大括号?
为什么要使用工会呢?为什么不这样做..
struct FltVector {
GLfloat x;
GLfloat y;
GLfloat z;
GLfloat w;
}
任何指针都非常赞赏(对不起双关语)
答案 0 :(得分:5)
union允许您为不同类型的变量“回收”相同的内存区域。通常,union会占用与其单个最大成员一样多的存储空间,在这种情况下可能需要4个浮点数。您可以查看sizeof
。
在这种情况下,union可能用于为结构中的相同浮点数提供1)替代名称(例如x
和r
共享相同的内存),以及2)访问< em>相同四个浮点数作为数组(例如x
和flts[0]
共享相同的内存)。有时,工会被用在各种“黑客”中,通常是非便携的,以访问某些数据类型的内部,例如,机器顺序中整数的单个字节。
答案 1 :(得分:5)
如果sizeof(GLfloat) == sizeof(float)
那么,已经分配了4个浮点数。
flts[0]
,r
和x
都将在此处引用相同的内存。
在union中,union中声明的每个不同变量都指向同一块内存。
这里我们有3个变量,2个结构和一个数组,每个变量都从内存中的同一点开始。
答案 2 :(得分:2)
那里有几个问题:)
@Arkku的大小是正确的。对齐也可以发挥作用,但可能不在这里。
为什么这是真的,在任何给定时间,联合只保留一个可能的值。出于这个原因,将结合放在一个结构中以及标识哪个值有效的东西(有时称为区分联合或 scrim )是很常见的。
一对括号用于联合,另一对用于阵列初始化。
答案 3 :(得分:1)
为什么在使用FltVector {{}}
时有两组大括号
看看整行,FltVector fltVec1 = {{1.0f, 1.0f, 1.0f, 1.0f}};
您正在初始化联合中第一个结构 中的四个浮动 。从粗体“in”中可以看出,嵌套有两个层次。如果嵌套的级别更深,你甚至可以有更多的花括号。
答案 4 :(得分:1)
在你的例子中,如果我们考虑变量的名称,联合肯定不会用来通过说x和r来访问同一个内存单元(因为半径和x坐标不合适),但是让用户为两者提供相同的参数。当你使用笛卡尔坐标时设置x,y,z,w要简单得多,并且在径向坐标上使用这些相同的名称会很尴尬。两者都比数组索引简单。您可能还有另一个参数,它给出了所提供坐标的类型(笛卡尔坐标或径向坐标)。因此,当pdbartlett调用它们时,你将拥有一个有区别的联盟。
在这种情况下,双层括号是无用的,因为数组可以通过数组(双层括号)或通过内部结构之一进行初始化。
更正:大括号的双重级别会避免将输入转换为GLFloats。
最后的细节:未命名的内部结构不是标准的C,做事的标准方法是给内部结构赋予名称,如
typedef union {
float flts[4];
struct {
float r;
float theta;
float phi;
float w;
} cartesian;
struct {
float x;
float y;
float z;
float w;
} radial;
} FltVector;
FltVector f = {1.0, 2.0, 3.0, 4.0 };
int main(int argc, char * argv[]){
printf("flts[0]=%f f.radial.r=%f f.cartesian.x=%f\n",
f.flts[0], f.radial.r, f.cartesian.x);
}
答案 5 :(得分:0)
如前所述,代码使用不同的名称和数据类型分配相同的内存。允许在命名的矢量组件(xyzw)上工作有时会很舒服,同时仍然能够在其他时间将矢量视为数组。
看起来笛卡尔和径向结构的名称是交换的。 “r”,“theta”和“phi”是径向坐标的通用名称,而不是笛卡尔坐标,通常表示为“x”,“y”和“z”。
我认为值得注意的是,使用不同的表示并不严格符合标准(但可能适用于所有现有的C实现),原因有两个: