2016-01-09 26 views
0

好的我碰到一个奇怪的东西,也许有人可以解释它。 源代码是(C++ 11):为什么sizeof给出错误的答案

‪#‎include‬ <stdio.h> 
struct xyz_ { 
    float xyz[3]; 
    float &x = xyz[0]; 
    float &y = xyz[1]; 
    float &z = xyz[2]; 
}; 

int main(int argc, char *argv[]) 
{ 
    xyz_ xyz; 
    xyz.x = 0; 
    xyz.y = 1; 
    xyz.z = 2; 
    xyz.xyz[1] = 1; 
    printf("as array %f %f %f\n",xyz.xyz[0],xyz.xyz[1],xyz.xyz[2]); 
    printf("as elements %f %f %f\n",xyz.x,xyz.y,xyz.z); 
    int sizexyz = sizeof(xyz); 
    int sizefloat = sizeof(float); 
    printf("float is %d big, but xyz is %d big\n",sizefloat,sizexyz); 
    return 0; 
} 

输出为:

as array 0.000000 1.000000 2.000000 
as elements 0.000000 1.000000 2.000000 
float is 4 big, but xyz is 24 big 

因此,结构工程,我所期望的,但尺寸的两倍大,因为它应该是。在结构中使用字符而不是浮点数会在运行时出现段错误。 我想使用struct xyz_作为浮点数组或单个浮点元素。

+0

我看到你是缩进代码的粉丝 –

+0

'使用字符给出段错误'不知道这是什么意思。 – dxiv

+0

为什么你认为24是错误的大小?我不会感到惊讶,如果它是40. –

回答

1

如何:

struct xyz_ 
{ 
    float xyz[3]; 
    float &x() {return xyz[0];} 
    float &y() {return xyz[1];} 
    float &z() {return xyz[2];} 
}; 

不一样美丽或优雅,但可能会降低大小一点,但我觉得this指针可能会占用额外的空间,不知道...

中当然,你将不得不使用x(),y()z()

+0

向谁downvoted:'''switch'''''如果else''为三个变量可能会有所帮助,编译器可以优化,也许,但代码变得更大。这个更短。 :-) –

+0

刚刚纠正,现在好点? –

+0

是的,这也是我想出来的。 – iplayfast

1

xyz_的大小是多少?

struct xyz_ { 
    float xyz[3]; 
    float *x = &xyz[0]; 
    float *y = &xyz[1]; 
    float *z = &xyz[2]; 
}; 

该引用还需要它自己的空间来存储它指向的信息。

4

这是未指定是否需要存储引用。在这种情况下,您的输出表明您的编译器已决定使用存储来实现参考x,yz

-1

C你可以做以下事情,但它在C++11不合法。

union xyz_ { 
    float xyz[3]; 
    struct { float x, y, z; }; 
}; 
+0

这是不合法的? – 6502

+0

向谁投降:是的,我清楚地知道这不是一个答案。同时,它不适合评论,但我相信它与被问到的问题有关。将C和C++翻译单元混合在同一个最终模块中并不是那么不寻常,有时出于像这样的语言差异的原因。 – dxiv

+0

@ 6502这不是标准。例如[为什么C++ 11不支持匿名结构,而C11呢?](http://stackoverflow.com/questions/8622459/why-does-c11-not-support-anonymous-structs-while-c11 -does)。 – dxiv

2

假设你添加另一个构造函数:

struct xyz_ { 
    float xyz[3]; 
    float &x = xyz[0]; 
    float &y = xyz[1]; 
    float &z = xyz[2]; 

    xyz_() 
    { 
    } 

    xyz_(float& a, float& b, float& c) 
     : x(a), y(b), z(c) 
    { 
    } 
}; 

应该明确的是,现在这三个xyz成员可以绑定到数组元素或可以被绑定到别的东西。

看起来你正在寻找的是

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

不幸的是,一些奇怪的原因(apparently mostly political)这是不支持的标准(尽管编译器实际上已支持)。

+0

是的,这是我的目标,我只是认为参考会更清楚。我将与&x(){return xyz [0]} – iplayfast