2012-05-01 3 views
0

Для следующего кода:Формат и аргументы несогласованность в PRINTF

#include <stdio.h> 
int main(){ 
    printf("%f", 5); 
    printf("%d", 5.01); 
} 

Первый оператор печати 0,000000 и второе утверждение будет печатать большое количество.

Я думал, что printf видит формат% f, выдает 4-байтовый аргумент из стека. Затем я просмотрел некоторые ссылки, в которых говорится, что функция printf преобразует float в double, поэтому аргумент 8 байтов. Поэтому я подумал, что это может напечатать непредсказуемое значение. Но как он мог распечатать 0,000000.

Второй также проветривается. Бинарный формат для 5.01 должен быть 0 10000001 01000000101000111101100 (0x40A051EC), он должен быть 1084248556 в десятичном формате, но результат этого заявления - 1889785610. Почему это происходит?

+3

[* Если какой-либо аргумент не является правильным типом для спецификатора формата ... тогда поведение не определено. *] (http://stackoverflow.com/a/5851578/1233508) – DCoder

+0

Undef поведение. Порядок байтов. –

ответ

3

Это сбивает с толку, но %d формат для целого, как %i (большинство людей ожидают, что это будет для двойной, так как %f для поплавка, но это не так). Вы не можете использовать его с двойным, вы должны использовать %f. То же самое с %f, вы не можете использовать с ним целое число; вы должны использовать float или double.

Кроме того, printf не проверяет типы, с которыми вы его используете, он просто слепо интерпретирует байты как типы, которые вы им сообщаете. Использование неправильных типов с неправильными спецификаторами типов дает неопределенное поведение, поэтому вы видите, что вы есть.

1

printf не является безопасным по типу, вы должны убедиться, что используете подходящие дескрипторы формата для типа данных, который собираетесь напечатать, или нет гарантии того, что будут получены результаты printf.

1

В первом случае, printf extects в double (из-за %f), но вы передаете int. Формат double отличается форма int (см IEEE-754 для наиболее часто используемого формата double)

второго схожа: printf ожидает int (из-за %d), но вы передаете в double

Как фактический значение интерпретируется, когда вы передаете неправильный тип, не определено (может зависеть от endiannes и т. д.)

+1

Что более важно на практике, это зависит от того, передаются ли разные типы в непересекающихся наборах регистров (например, целые числа/указатели в GPR (rdi, rsi, rdx, ...) и с плавающей запятой в векторных регистрах (xmm0, xmm1, .. .)). –

Смежные вопросы