Я немного смущен. Во время разработки одной функции, которая основывается на предопределенных параметрах, переходите к параметрам функции sprintf, необходимым по их типу, я нашел действительно странное поведение (что-то вроде «Это% f% d example», typeFloat, typeInt).Union float и int
Пожалуйста, обратите внимание на следующий раздели рабочий код:
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;
}
Мой ожидаемый результат будет для printf("Number is %d\n", p.paramType == Param::typeInt ? p.i : p.f);
Number is -10
, но на самом деле напечатаны
Number is 0
Я поставил точка останова после инициализации параметра p, и хотя p.paramType
определяется как typeInt
, фактический выход для if
был -10.0000. Проверка p.f дает некоторое неопределенное значение, как ожидалось, и p.i показывает -10 также как и ожидалось. Но p.paramType == Param::typeInt ? p.i : p.f
в окне просмотра оценивается в -10.000000.
Я добавил второй Printf, который печатает как поплавок, и теперь выход является
Number is 0
Number is -10.000000
Так на самом деле, почему это происходит? Возможно ли, что это ошибка в Visual Studio (я использую VS2012)?
Update:
std::cout<< (p.paramType == Param::typeInt ? p.i : p.f);
дает правильное значение -10.
Благодарим вас за ответ. Я не могу передать полное выражение в int как p.paramType также может быть float (я просто использовал int как пример выше). Почему он всегда плавает, если я подаю в целую часть объединения одно число? – Izzy
Если вы не хотите передавать его в int, тогда нет смысла распечатывать его как целое. Поэтому либо всегда печатайте float, либо когда вы печатаете int, на самом деле даете ему int :-) Результат выражения (например, '?:') Может быть только одного типа; когда два подвыражения имеют разные типы, [выполняется неявное преобразование типа] (http://stackoverflow.com/q/8535226/21475). – Cameron
А я вижу. Я узнал что-то новое сегодня :). Я не знал, что о тернарном утверждении может возвращаться только один тип. Но я не могу отличить все от int, потому что это может быть float вместо int. Решение состоит в том, чтобы оставить все плавающим и сделать формат как% .0f, который будет округлять число с плавающей точкой до целого числа. – Izzy