Как printf и co различают float и double - PullRequest
42 голосов
/ 18 июня 2011

Поскольку он не является строго типизированным, я подумал, что он просто выбрал правильный объем памяти и интерпретировал его в зависимости от типа аргумента. Но float и double используют% f и имеют разные размеры.

P.S. Я вижу, как может работать продвижение через копирование значения в temp и приведение (это правильно?) но как это работает для scanfs / sscanf?

1 Ответ

63 голосов
/ 18 июня 2011

Это не дифференцирует.Невозможно получить float в качестве переменной: любой предоставленный вами аргумент float сначала повышается до double.

6.5.2.2 / 6 определяет «продвижения аргументов по умолчанию», а / 7утверждает, что продвижение аргументов по умолчанию применяется к «конечным аргументам», то есть переменным, обозначаемым ....

, как это работает для scanfs / sscanf?

Для формата %f для scanf требуется указатель на float.%lf требуется указатель на double, %Lf требуется указатель на long double.

копирование значения в темп и приведение (это правильно?)

Если вы предоставите аргумент float, то реализация создаст временный тип типа double, инициализирует его значением float и передаст его как vararg.Приведение по определению - это явное преобразование с использованием оператора приведения - вы можете при желании привести в порядок, чтобы читатель точно понял, что происходит, но float f = 3; printf("%f", f); точно так же, как float f = 3; printf("%f", (double)f);.Продвижение аргумента по умолчанию имеет то же значение, что и приведение.

...