2013-10-01 3 views
-5

Каков выходной сигнал?Формат строки в printf

main() 
{ 
    float a=4; 
    int i=2; 
    printf("%f %d",i/a,i/a); 
    printf("%d %f",i/a,i/a); 
} 

Ответ Я получаю это: 0.500000 00 0.000000

Причина: В первом printf, %f=i/a=2/4=int/float поэтому неявное приведение делается и i становится float, которая вызывает результат float (т.е. 0.500000).

По умолчанию точность поплавка равна 6, после десятичной цифры 6 цифр, а затем %d=i/a=2 /4=0.500000, но %d формат строки печатать только целое число, поэтому 0 печатается и после десятичных значений отбрасывается.

printf с %d=i/a=2/4 печать 0 имеет ту же концепцию; однако %f=i/a=2/4=0.000000 последний результат я не понял.

+0

Почему бы не попробовать? [Ideone.com] (http://ideone.com/) Вы можете попробовать всевозможные вещи, даже если не перед ПК, загруженным всем необходимым для этого ... – ppeterka

+0

Можете ли вы точно определить, что это такое что вы не понимаете? – nhgrif

+2

«неявное литье» - это оксюморон. Кастинг является явным по определению. Слово, которое вы ищете, - это «неявное преобразование». –

ответ

2

Неопределенное поведение: все типы данных в printf неявно плавают. Это связано с тем, что i/a имеет тип float, так как int datum повышается до плавающей запятой. Поэтому вы должны использовать %f исключительно в своем printf.

4

Этот простой undefined behavior указать неправильный спецификатор формата для printf в обоих случаях выражение i/a будет выдвинут на double и вы указываете, что это int для одного аргумента. C99 draft standard в разделе 7.19.6.1функции fprintf, какой раздел printf «s ссылается на для строки формата пункта говорит:

Если спецификация преобразования является недействительным, поведение не определено [.... ]

Вы должны включить предупреждение, но и gcc и clang предупредит об этом не сгибать их вообще, в gcc я получить следующее сообщение:

warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘double’ [-Wformat] 
+0

вы уверены? Будет ли 'int' не повышаться до' float'? – Bathsheba

+2

@Bathsheba. Вы правы, что 'i/a'' 'float', но в переменной аргументной функции, такой как' printf', 'float' повышается до' double'. –

3

i/a выражение всегда к float поскольку один из операндов float. Во время печати мы используем спецификаторы %d и %f. Поэтому, когда мы используем %f, он будет (должен) всегда равным 0,5, и когда мы используем %d, он должен быть undefined.

В Linux (Ubuntu) с компилятором GCC я получаю следующий вывод (добавил \n после печати первой страницы для ясности):

0.500000 2047229448 
899608576 0.500000 
Смежные вопросы