C:为什么同一个地址有两个不同的值?

C:为什么同一个地址有两个不同的值?,c,gcc,union,C,Gcc,Union,一个相当简单的代码: #包括 联富{ INTA; 浮球b; }; int main(){ 联富吧; bar.a=10; printf(“地址:%p%p\n”,&(条形图a),&(条形图b)); printf(“值:%d%f\n”,条形图a,条形图b); 返回0; } 结果是: Addresses: 0x7ffe8eda48a4 0x7ffe8eda48a4 Values: 10 0.000000 两个工会成员的地址是一样的(应该是一样的)。但这难道不意味着这些地址的值也将是相同的吗?事实似乎

一个相当简单的代码:

#包括
联富{
INTA;
浮球b;
};
int main(){
联富吧;
bar.a=10;
printf(“地址:%p%p\n”,&(条形图a),&(条形图b));
printf(“值:%d%f\n”,条形图a,条形图b);
返回0;
}
结果是:

Addresses: 0x7ffe8eda48a4 0x7ffe8eda48a4
Values: 10 0.000000
两个工会成员的地址是一样的(应该是一样的)。但这难道不意味着这些地址的值也将是相同的吗?事实似乎并非如此


谢谢:)

如果尝试读取上次写入的联合成员以外的联合成员,则结果定义不明确(在某些特殊情况下,联合包含具有兼容类型的结构除外)。报告说:

如果用于读取联合对象内容的成员与上次用于在对象中存储值的成员不同,则该值的对象表示的适当部分将重新解释为6.2.6中所述的新类型中的对象表示(有时称为“类型双关”的过程)。这可能是一个陷阱表示

因此,如果您存储到
bar.a
中,然后尝试读取
bar.b
,它会将该内存的内容重新解释为
浮点值。您不会得到相同的值,因为浮点10的表示与整数10完全不同

强制转换
(int)bar.b
无法解决问题,因为这将首先将内容解释为
浮点值,然后将其转换为整数

您可以做的是使用指向成员的指针强制转换。但是,我认为这可能违反了严格的别名规则

printf("%d %d\n", foo.a, *(int *)&foo.b);

您将相同的数据解释为不同的类型。为什么期望值相同?只读取写入的成员的最后一个成员是有效的。为什么期望得到相同的值?它不进行类型转换,而是将内存内容解释为指定的数据类型。您需要了解浮点数字是如何以IEEE-754格式存储的。当读取为
b
时,并非为
a
输入的每个整数都与有效的
float
相对应。您得到的两个明显不同的值具有相同的位模式。只是有不同的解释。类似地,
'A'
65
是解释位模式的不同方式
01000001
。非常感谢您的解释:)。我最初的假设是,
float
int
的表示是兼容的,现在我明白了,这是完全错误的。请看@MihirChaturvedi,我打赌你对JavaScript有更多的经验,是吗?@datenwolf哈哈是的,这是我的主要语言,描述一个工会成员的阅读,而不是最后一个写为“实现定义”的阅读是不正确的。C标准没有规定实现定义的行为,只是实现必须定义它,但将联合内容重新解释为新类型受到C 2018 6.2.6“类型表示”中各种规则的约束。这些规则包含实现定义的方面,但最终不是,实现定义。