为什么下面的C代码输出1? #包括 联合p { int x; chary; }k={1,97}; int main() { printf(“%d\n”,k.y); }
这是代码。当我用67替换97时,输出是1。该为什么下面的C代码输出1? #包括 联合p { int x; chary; }k={1,97}; int main() { printf(“%d\n”,k.y); },c,C,这是代码。当我用67替换97时,输出是1。该1如何打印?因为联合,而不是结构,覆盖其成员。初始化两个成员是没有意义的。编译器实际上应该警告您“初始化者过多”或类似的情况。尝试启用更多警告(个人推荐的gcc/clang:-std=c11-Wall-Wextra-pedantic) 对于联合,初始值设定项(不带指示符)总是初始化第一个联合成员。不能让一个联合的多个成员同时持有一个值,它们都共享相同的内存,因此初始化多个成员是没有意义的。如果您使用指示符,最后一个将“获胜” 编译器只需删除97并使用1
1
如何打印?因为联合
,而不是结构
,覆盖其成员。初始化两个成员是没有意义的。编译器实际上应该警告您“初始化者过多”或类似的情况。尝试启用更多警告(个人推荐的gcc
/clang
:-std=c11-Wall-Wextra-pedantic
)
对于联合
,初始值设定项(不带指示符)总是初始化第一个联合成员。不能让一个联合的多个成员同时持有一个值,它们都共享相同的内存,因此初始化多个成员是没有意义的。如果您使用指示符,最后一个将“获胜”
编译器只需删除97
并使用1
初始化p.x
。这并不能保证读p.y
会给你1
,但在一台小小的endian机器上,这会发生 您的程序未定义-您只能初始化联合的一个成员,因为所有成员都存储在同一地址。我很惊讶你的C编译器对此不感兴趣,你是否禁用了警告?一旦跳转到undefined,就不知道编译器将做什么。因为它是一个并集,只需要一个初始化值。第二个被忽略了 您使用了错误的格式说明符。只能为k
指定1个初始值设定项-您显示的内容不应编译。没有特定的名称(指定的初始值设定项),它会初始化定义的第一个成员,x
@SamiKuhmonen:No-因为字符在默认参数提升规则下被转换为int
,%d
完全可以。@JonathanLeffler我不认为过多的初始值设定项会违反约束吗?好吧,他们只是被忽略了。活到老学到老,也不知道在这种情况下会发生什么。这个程序不是未定义的。从技术上讲,它不是未定义的,但它是非常糟糕的编码实践。根据系统的长度,1将存储在(可能)四字节内存区域的高或低地址中。字符总是从最低的字节读取,因此程序的行为将取决于它在哪个处理器上运行。[link]{}第5-7段说“必须”,因此程序无效。未定义的位是关于编译器选择哪个初始值设定项,而不是解释的结尾。请注意,GCC(7.2.0无论如何)警告过多的初始值设定项,即使没有引发警告的选项(GCC-c union41.c
)。
#include <stdio.h>
union p
{
int x;
char y;
} k = {1, 97};
int main()
{
printf("%d\n", k.y);
}