2013-10-28 1 views
2

Я вижу разные результаты для двух программ, которые я ожидаю, чтобы получить тот же результат, то первый случай:Неожиданные результаты при использовании Printf

int money; 

printf("Enter the price of the car: "); 
scanf("%d", &money); 

printf("\nResult: %d .\n", money+money*0.4); 

второй случай:

int money; 

printf("Enter the price of the car: "); 
scanf("%d", &money); 

money=money+money*0.4; 

printf("\nResult: %d .\n", money); 
return 0; 

В первом в случае, если результат printf равен 0, но не во втором случае. Почему я вижу эти разные результаты?

+1

Вы должны включить предупреждение, чтобы понять. В первом случае это 'формат«% d»рассчитывает ввести«Int», но аргумент имеет тип 2«double'' Во втором случае 'преобразование в„Int“от„двойной“может изменить свою value' , И я думаю, предупреждение очень хорошо объясняет. –

ответ

1

money+money*0.4 неявно лидирует money, чтобы удвоить и, таким образом, сделать %d неправильным спецификатором формата для этого значения.

7

формат %d спецификатор говорит printf, что вы передаете в Int, но в первом случае вы передаете в двойной который также undefined behavior и поэтому результаты не являются надежными. Результат:

money+money*0.4 

является двойного поскольку плавающих постоянной является двойного, если он не имеет суффикса, такой как f и результатов умножения и дополнения является двойного, как хорошо из-за обычных арифметических преобразований, на которые распространяются обе операции, и которая приведет к преобразованию значения money в double для операции.

Во втором случае вы правильно переходящими в Int и так как вы назначая результат money:

money=money+money*0.4 

будет укоротить двойное значения . Я не уверен, что компилятор вы используете, но оба clang и gcc без предупреждения флагов и предупреждают о неправильном спецификаторе формата, gcc, например, говорят:

предупреждение: формат «% d» ожидает аргумент типа «ИНТ ', но аргумент 2 имеет тип' double '[-Wformat]

Так что, если вы не видите никаких предупреждений для этой линии, вы должны изучить настройку уровней предупреждений выше.

Для полноты раздел draft C99 standard7.19.6.1Функция fprintf, которая также охватывает printf относительно спецификаторов формата, в пункте говорит:

Если спецификация преобразования является недействительным, поведение не определено. 248) Если какой-либо аргумент не соответствует типу для соответствующей спецификации преобразования, поведение не определено.

3

Проверить умножение в строке 7.

Вы можете изменить последние строки в:

float price = money * 1.4; 
printf("\nResult %f.\n", price);