Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
寻求C联盟的清晰性_C_Unions - Fatal编程技术网

寻求C联盟的清晰性

寻求C联盟的清晰性,c,unions,C,Unions,好的,我想我知道如何使用这个(或者,这就是我看到它的用法)ie 但我并不是真的在摸索工会宣布了多少存储量(4个浮动?8个浮动?12个浮动?),怎么说?为什么?还有为什么在使用FltVector{{}时使用两组大括号 为什么要使用工会呢?为什么不 FltVector fltVec1 = {{1.0f, 1.0f, 1.0f, 1.0f}}; float aaa = fltVec1.x; etc. ? 任何非常受欢迎的指针(抱歉这个双关语)联合允许您为不同类型的变量“回收”相同的内存区域。通常情况

好的,我想我知道如何使用这个(或者,这就是我看到它的用法)ie

但我并不是真的在摸索工会宣布了多少存储量(4个浮动?8个浮动?12个浮动?),怎么说?为什么?还有为什么在使用FltVector{{}时使用两组大括号

为什么要使用工会呢?为什么不

FltVector fltVec1 = {{1.0f, 1.0f, 1.0f, 1.0f}};
float aaa = fltVec1.x;
etc.
?


任何非常受欢迎的指针(抱歉这个双关语)

联合允许您为不同类型的变量“回收”相同的内存区域。通常情况下,工会占用的存储空间与其最大的单个会员国相同,在这种情况下,可能需要4个浮点数。您可以使用
sizeof
进行检查

在这种情况下,union可能用于1)为结构中的相同浮点数提供替代名称(例如
x
r
共享相同的内存),以及2)作为数组访问相同的四个浮点数(例如
x
flts[0]
共享相同的内存)。有时在各种“黑客”中使用联合,通常是不可移植的,以访问某些数据类型的内部,例如机器顺序中整数中的单个字节

如果
sizeof(GLfloat)=sizeof(float)
则分配了4个浮点

flts[0]
r
x
都将在此处引用同一块内存

在联合体中,联合体中声明的每个不同变量都引用同一块内存

这里有3个变量,2个结构和一个数组,每个变量都从内存中的同一点开始。

这里有几个问题:)

@Arkku的尺寸是对的。对齐也可以发挥作用,但这里可能不起作用

这一点之所以成立,是因为在任何给定的时间,工会只持有其中一种可能的价值观。由于这个原因,结构中的并集通常与标识哪个值有效的东西(有时称为有区别的并集或scrim)一起出现

一对大括号用于联合,另一对用于数组初始化器

为什么在使用FltVector{{}时使用两组大括号

看看整行,
FltVector fltVec1={{1.0f,1.0f,1.0f,1.0f}

您正在初始化联合体的第一个结构中的四个浮动。从粗体的“in”可以看出,嵌套有两个级别。如果嵌套的深度更深,甚至可以有更多的大括号。

在您的示例中,如果我们考虑变量的名称,则联合肯定不会被用来通过X和R访问相同的存储单元(如半径和x坐标将不适合),但是留给用户为两者提供相同的参数。当你使用笛卡尔坐标时,设置x,y,z,w要简单得多,而使用这些相同的名称来表示径向坐标则会很尴尬。两者都比数组索引简单。您可能还有另一个参数,用于提供所提供坐标的类型(笛卡尔坐标或径向坐标)。因此,你将拥有一个被pdbartlett称为歧视的联盟

在这种情况下,双级大括号是无用的,因为数组可以通过数组(双级大括号)或内部结构之一初始化

更正:双级别大括号避免将输入转换为GLFloats

最后一个细节:未命名的内部结构不是标准的C,标准的方法是为内部结构命名,如

   struct FltVector {
        GLfloat x;
        GLfloat y;
        GLfloat z;
        GLfloat w;
   }

如前所述,代码使用不同的名称和数据类型分配相同的内存。有时允许处理命名向量组件(xyzw)会比较舒服,但在其他时候仍然可以将向量作为数组处理

不过,看起来笛卡尔结构和放射状结构的名称互换了。“r”、“θ”和“φ”是径向坐标的常用名称,而不是笛卡尔坐标,笛卡尔坐标通常表示为“x”、“y”和“z”

我认为值得注意的是,使用不同的表示法并不严格符合标准(但可能在所有现有的C语言实现中都可以正常工作),原因有两个:

  • 读取不是最近编写的工会成员会产生未定义的结果。不过,任何正常的实现都将返回存储在该内存中的值
  • 编译器可能会在结构成员之间添加填充(出于性能原因),而数组永远不会被填充。不过,这种情况在任何现代CPU上都不太可能发生

  • 在这种情况下是这样的:4个浮点(如果GLfloat等于float)是的,但是在这里我们可以远程删除一组大括号,因为它将初始化第一个内部结构。它不是“更常见”,它实际上是语言所需要的。由于非标准的编译器扩展,它没有这些名称进行编译。@AndreyT:我会编辑答案,我没有签入标准(无论如何,我不是标准的忠实信徒,我认为编译器是真实的。在我看来,标准只是避免过多熵和指导语言进化的工具)。
       struct FltVector {
            GLfloat x;
            GLfloat y;
            GLfloat z;
            GLfloat w;
       }
    
    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);
    }