2014-10-03 7 views
0
#include <stdio.h> 

    int main(void) 
    { 
     double a = 1234.5f; 
     int b = 71; 
     int c = 68; 
     int d;                                
     printf("%d %d %d %d\n", a,b,c,d); 
     return 0; 
    } 

Выход:нечетное поведение Printf

0 1083394560 71 68 

Здесь, почему б дает значение мусора, в то время как с дает значение б, г дает значение с даже не инициализирован?

+3

Обратите внимание на предупреждения компилятора. Несоответствие спецификаторов формата и входных данных вызывает * неопределенное поведение *. – DCoder

+0

** Dcoder **, я видел предупреждения компилятора, я написал код намеренно, я просто хочу знать причину этого bahaviour. – JagsVG

ответ

6

"%d" в формате спецификатор ожидает int, но a имеет тип double, так что это неопределенное поведение.

Одна из возможностей того, что может случиться, заключается в том, что компилятор ставит переменные один за другим в стек. Если на вашей платформе размер double составлял 8 байтов и в два раза больше int, то компилятор делает неправильное предположение о том, где читать значения. Но опять же, это неопределенное поведение, компилятор может делать все, что захочет, с вашим кодом.

1

для печати двойной спецификатор формата значение должно быть %f не %d

printf("%f %d %d %d\n", a,b,c,d); 
0

Вы используете спецификатор формата для int и передаете аргумент типа double.

printf("%d %d %d %d\n", a,b,c,d); 

вместо

printf("%f %d %d %d\n", a,b,c,d); 

Когда аргументы printf не соответствуют спецификатору преобразования, вы бежите в неопределенное поведение.

От http://en.cppreference.com/w/cpp/io/c/fprintf

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

2

Поведение здесь не определено. Но если вы используете машинное объяснение 32bt просто:

Вы печатаете каждый элемент как int (% d). Int - 4 байта. Двойной - 8 байтов и имеет другое представление. Все аргументы передаются через стек для printf. Итак, первые 8 байтов a, затем 4 байта b, затем 4 байта c, затем 4 байта d.
printf принимает аргумент const char и извлекает аргументы из стека в соответствии с ним; первый% d 4 байта должен быть целым, но он находит там половину двойного и отпечатка мусора. Затем% d next int, но printf находит в стеке вторую половину двойной (снова мусор). Затем% d, опять 4 байта. Он находит b и печатает его. Затем снова% d 4-байтовое целое, печатает c. В строке нет%, поэтому printf прекращает печать.

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