这是一个包含两种类型的变量int
和char
的联合。如果我为int
变量分配了一些值,那么char
变量中会出现什么?
例如
union a {
int x;
char j;
char k;
} ua;
int main(){
ua.x = 0xabcd;
printf("%x",ua.j);
}
这里将打印什么值以及如何打印?
答案 0 :(得分:3)
按照C11标准:
6.2.6类型的表示形式
6.2.6.1常规
...
5某些对象表示形式不必表示对象类型的值。 如果对象的存储值具有这种表示形式,并由执行以下操作的左值表达式读取 没有字符类型,则行为是不确定的。如果产生这样的表示 通过左值表达式修改对象的全部或任何部分的副作用 没有字符类型,则行为未定义。50)这种表示称为 陷阱表示。
但是这里的左值表达式具有char
类型,因此这是定义明确的行为。
与此相关的是
6.5.2.3结构和联合成员:
...
95)如果用于读取联合对象内容的成员与上次使用该成员的成员不同 在对象中存储一个值,该对象表示的相应部分将重新解释该值 作为6.2.6中描述的新类型的对象表示形式(有时称为“‘type punning’)。这可能是陷阱的表示形式
printf
语句将实际打印的内容取决于系统的耐久性,也就是说,它是实现定义的。
答案 1 :(得分:2)
此代码可以帮助您了解正在发生的事情:
union a {
int x;
char j;
char k;
}ua;
int main(){
ua.x = 0xabcd;
printf("%x\n",ua.x); // Print x as hexadecimal: abcd
printf("%x\n",ua.j); // Print j as hexadecimal: ffffffcd
printf("%x\n",ua.k); // Print k as hexadecimal: ffffffcd
printf("%d\n",ua.x); // Print x as decimal: 43981
printf("%c\n",ua.j); // Print j as char: �
printf("%c\n",ua.k); // Print k as char: �
}
将0xabcd写入一个int时,该int的存储空间将填充此十六进制数字(abcd),十进制值为43981。您可以分别打印%x和%d这两个值。
正如@Jonathan Leffler所说,j和k只是引用联合的相同字节的不同名称。这就是为什么在两种情况下%x都以“ cd”(完成写入的值的最后一个字节,由于您的系统似乎使用大字节序)打印一个值的原因。 “ char值”表示为。。
如果您想知道为什么在值前打印出ffffff,请检查:Printing hexadecimal characters in C。