在C中操纵并集变量

时间:2019-02-26 10:56:31

标签: c union

这是一个包含两种类型的变量intchar的联合。如果我为int变量分配了一些值,那么char变量中会出现什么?

例如

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

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

2 个答案:

答案 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