下面的代码每次都会输出不同的数字。apples.num打印2是正确的,apples.weight每次打印不同的数字,甚至打印出“ nan”,我不知道为什么会这样。真正奇怪的是,double(apples.volume)打印出了2.0 ..有人可以向我解释吗?#include <stdio.h>typedef union { short num; float weight; double volume;} Count;int main(int argc, char const *argv[]){ Count apples; apples.num = 2; printf("Num: %d\nWeight: %f\nVolume: %f\n", apples.num, apples.weight, apples.volume); return 0;} 最佳答案 在我看来,您不太了解工会是什么。联合的成员是重叠的值(换句话说,Count联合的三个成员共享相同的空间)。假设,仅出于演示目的,short是16位(2字节),float是32位(4字节),而double是64位(8字节),则并集是8字节大小。在小尾数格式中,num成员指的是前2个字节,weight成员指的是前4个字节(包括num的2个字节),而volume成员指的是完整的8个字节(包括num的2个字节和weight的四个字节)。最初,您的联合包含垃圾,即一些未知的位模式,让我们这样显示它(十六进制):GG GG GG GG GG GG GG GG // GG stands for garbage, i.e. unknown bit patterns如果将num设置为2,则前两个字节是0x02 0x00,但其他字节仍然是垃圾:02 00 GG GG GG GG GG GG如果读取weight,则只需读取前四个字节(解释为float),因此float包含字节02 00 GG GG由于浮点值的格式与short这样的整数类型完全不同,因此您无法预测这些字节(即特定的位模式)代表什么。它们不代表您可能想要的浮点值2.0f。实际上,float的“更重要”部分存储在高字节中,即weight的“垃圾”部分中,因此它几乎可以是任何东西,包括NaN,+infinity,等同样,如果您阅读-infinity,则您有一个volume,该字节由字节组成02 00 GG GG GG GG GG GG并且也不一定代表2.0(尽管偶然,如果恰好在正确的位置设置了正确的位,并且在显示此值时将低位四舍五入,它可能会非常接近)。联合并不意味着要从double正确转换为int或float。它们只是为了能够将不同类型的值存储为同一类型,而从您设置的另一个成员读取数据只是意味着您将联合中存在的许多位重新解释为完全不同的东西。您没有转换。那么,如何转换?这很简单,不需要联合:short num = 2;float weight = num; // the compiler inserts code that performs a conversion to floatdouble volume = num; // the compiler inserts code that performs a conversion to double关于c - 意外的联盟行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24834488/
10-12 06:27