C语言中联合变量的操作

bvjxkvbb  于 2023-03-17  发布在  其他
关注(0)|答案(2)|浏览(128)

这是一个包含两种类型变量intchar的并集。如果我给int变量赋值,那么char变量中会出现什么?
例如,

union a {
  int x;
  char j;
  char k;
} ua;
int main(){
  ua.x = 0xabcd;
  printf("%x",ua.j);
}

这里什么值将被打印以及如何打印?

py49o6xq

py49o6xq1#

根据C11标准:

6.2.6类型的表示
6.2.6.1概述

...
5某些对象表示不需要表示对象类型的值。**如果对象的存储值具有这样的表示,并且由没有字符类型的左值表达式读取,则行为未定义。**如果这样的表示是由通过没有字符类型的左值表达式修改对象的全部或任何部分的副作用产生的,行为是未定义的。50)这样的表示被称为陷阱表示。
但是这里的左值表达式有char类型,所以这是一个定义良好的行为。
同样相关的是来自

6.5.2.3结构和工会成员:

...
95)如果用于读取联合对象内容的成员与上次用于在对象中存储值的成员不同,则该值的对象表示的适当部分将被重新解释为新类型中的对象表示,如6.2.6中所述(该过程有时称为“类型双关”)。这可能是陷阱表示
printf语句实际打印的内容将取决于系统的字节序,也就是说,它是由实现定义的。

hof1towb

hof1towb2#

此代码可能有助于您了解正在发生的情况:

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 .

相关问题