【问题标题】:Union behaving differently on using different format specifier [closed]联盟在使用不同的格式说明符时表现不同[关闭]
【发布时间】:2019-08-27 17:53:49
【问题描述】:
#include <stdio.h>
union p{
int x;
char y;
};
int main(){
union p a;
a.y = 60;
a.x = 12;
printf("%f ",a.y);
printf("%d ",a.y);
printf("%d",a.x);
}

在上面的输出中是 0.000000 和 12 和 12 但我认为它必须是 12 和 12 和 12 有人可以解释一下。

【问题讨论】:

  • 您为什么希望%f 打印任何合理的东西?它与联合中的任何一种类型都不匹配,并且无论如何,没有任何机制可以执行必要的转换。
  • a.y = 60; a.x = 12; 是矛盾的。在union 中不能两者兼有。 union 不是 struct
  • 另外,当您将 12 放入 .x 并从 .y 中提取一个字符值时,也不能保证为 12(也就是说,即使您使用 @987654331 打印它也不能保证@,它甚至不能保证是 char 值 12)。
  • .. 仅当 little-endian 时。

标签: c


【解决方案1】:

a.y 是一个字符,但在这里

printf("%f ",a.y);

您将其打印为double。这是未定义的行为,即您可以获得任何类型的输出。

始终使用正确的格式说明符。

确保遵守编译器警告!对于 gcc 我得到了

main.cpp: In function 'main':
main.cpp:12:10: warning: format '%f' expects argument of type 'double', but argument 2 has type 'int' [-Wformat=]
   12 | printf("%f ",a.y);
      |         ~^   ~~~
      |          |    |
      |          |    int
      |          double
      |         %d

这说明一切都错了。

如果你把代码改成

#include <stdio.h>
union p{
    int x;
    char y;
    float z;
};

int main(){
    union p a;
    a.y = 60;
    a.x = 12;
    printf("%.200f ",a.z);
    printf("%d ",a.y);
    printf("%d",a.x);
}

代码变为有效的 C 代码并给出以下结果:

0.00000000000000000000000000000000000000000001681558157189780485108475499947899357536314330251818926108481940667749299223032721783965826034545898437500000000000000000000000000000000000000000000000000000 12 12

在大多数小端机器上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-28
    • 2016-04-04
    • 2016-07-27
    • 2011-12-28
    • 1970-01-01
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多