Union float和int

Izz*_*zzy 2 c++ unions visual-studio-2012

我有点困惑.在开发基于预定义参数的一个函数期间,根据它们的类型传递给sprintf函数所需的精确参数,我发现了非常奇怪的行为(类似于"这是%f%d示例",typeFloat,typeInt).

请查看以下剥离的工作代码:

struct Param {
 enum { typeInt,    typeFloat   } paramType;
 union {
    float f;
    int i;
 };
};

int _tmain(int argc, _TCHAR* argv[])
{
 Param p;
 p.paramType = Param::typeInt;
 p.i = -10;

 char chOut[256];
 printf( "Number is %d\n", p.paramType == Param::typeInt ? p.i : p.f );
 printf( "Number is %f\n", p.paramType == Param::typeInt ? p.i : p.f );
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的预期产量将是 printf( "Number is %d\n", p.paramType == Param::typeInt ? p.i : p.f );

Number is -10
Run Code Online (Sandbox Code Playgroud)

但它确实打印出来了

Number is 0
Run Code Online (Sandbox Code Playgroud)

我在Param p初始化之后放了一个断点,虽然p.paramType定义为typeInt,但实际输出为if-10.0000.检查pf会按预期给出一些未定义的值,pi也会按预期显示-10.但p.paramType == Param::typeInt ? p.i : p.f在观察窗口评估为-10.000000.

我添加了第二个printf,将其打印为float,现在输出为

Number is 0
Number is -10.000000
Run Code Online (Sandbox Code Playgroud)

那么为什么会这样呢?这可能是Visual Studio中的一个错误(我使用的是VS2012)吗?

更新:

std::cout<< (p.paramType == Param::typeInt ? p.i : p.f);
Run Code Online (Sandbox Code Playgroud)

给出正确的-10值.

Cam*_*ron 5

这是因为表达式的结果类型p.paramType == Param::typeInt ? p.i : p.f总是浮点数(只是取决于不同paramType),但是您的第一个格式字符串需要一个整数.

以下应该按预期工作:

printf("Number is %d\n", (int)(p.paramType == Param::typeInt ? p.i : p.f));
Run Code Online (Sandbox Code Playgroud)

cout版本为您提供了预期的输出,因为insert(float)表达式的类型是自动推导出来的,因此它将其格式化为float.它与你的第二个基本相同printf.