【发布时间】:2013-04-30 00:58:54
【问题描述】:
#include <stdio.h>
union Endian
{
int i;
char c[sizeof(int)];
};
int main(int argc, char *argv[])
{
union Endian e;
e.i = 1;
printf("%d \n",&e.i);
printf("%d,%d,\n",e.c[0],&(e.c[0]));
printf("%d,%d",e.c[sizeof(int)-1],&(e.c[sizeof(int)-1]));
}
输出:
1567599464
1,1567599464,
0,1567599467
LSB 存储在低位地址,MSB 存储在高位地址。这不应该是大端吗?但我的系统配置将其显示为小端架构。
【问题讨论】:
-
@tez 每当您打印地址时,将它们转换为
void*并使用%p格式说明符是正确的。%d是一个纯粹的禁忌,因为它用于签名-整数。地址从不签名。 -
@shazin 当 OP 使用
e.i=1,e.c[0] 也获得了它的值,因为它们具有相同的地址。这就是联合的全部意义,与结构相反。 -
@tez 因为
%p期望,就像 %d 期望整数,而不是浮点数 -
@tez 最好遵守规则。如果您使用
%u代替`%p,有时可能会得到相同的结果,但这并不总是有保证的。所以最好坚持规则。 -
@Koushik 从与最后存储在 C 中的联合成员不同的联合成员中读取数据本身并不是 UB(在 C++ 中是这样)。您可能会得到一个陷阱表示,如果读取的成员大于存储的成员,则与存储的成员不对应的字节具有不确定的值。两者都不适用于此处,因此行为不是未定义的(但未指定,因为它取决于字节序)。
标签: c math arithmetic-expressions