C printf с использованием% d и% f - PullRequest
9 голосов
/ 16 февраля 2010

Я работал над этой программой и заметил, что использование% f для double и% d для float дает мне что-то совершенно другое. Кто-нибудь знает, почему это происходит?

int main ()
{
 float a = 1F;
 double b = 1;

 printf("float =%d\ndouble= %f", a, b);
}

Это вывод

float = -1610612736
double = 190359837192766135921612671364749893774625551025007120912096639276776057269784974988808792093423962875123204096.0000

Ответы [ 4 ]

4 голосов
/ 16 февраля 2010

Из-за того, как работают переменные параметры, C не имеет представления о типе значения, которое вы фактически передаете, кроме %d и %f. Когда вы передаете переменный параметр, вы в основном выполняете (void*)&myvalue, потому что ни компилятор, ни функция во время выполнения не могут определить тип переменной, за исключением того, что указано в строке форматирования. Таким образом, даже несмотря на то, что существует неявное преобразование, компилятор не знает, что это необходимо.

Что ж, double - это 8 байтов в большинстве систем, а float - 4 байта. Таким образом, эти два типа не являются двоично-совместимыми, как есть. И это все равно, что пытаться интерпретировать строку как двойной тип или какой-либо другой несовместимый тип.

4 голосов
/ 16 февраля 2010

%d означает десятичное число и ожидает аргумент типа int (или некоторый целочисленный тип меньшего числа со знаком, который затем будет повышен). Типы с плавающей точкой float и double оба передаются одинаково (повышается до double), и оба они используют %f. В C99 вы также можете использовать %lf для обозначения большего размера double, но это чисто косметически (обратите внимание, что при scanf повышение не происходит, и это действительно имеет значение).

3 голосов
/ 16 февраля 2010

Это связано с внутренним представлением данных. Вы пытаетесь напечатать число с плавающей точкой, как если бы оно было int, которое имеет совершенно другое внутреннее (двоичное) представление.

Корпус double аналогичен. У вас, вероятно, есть мусор (любые данные) после переменной с плавающей точкой. Этот мусор интерпретируется как часть двойного значения.

0 голосов
/ 16 февраля 2010

% d печатает целое число, поэтому ваш printf интерпретирует вашу переменную a как int.

С gcc 3.4.6 я получаю 0 для обоих значений в вашем коде (после удаления F из инициализации, поскольку это привело к ошибке компилятора). Я подозреваю, что это связано с той частью переменной, которая интерпретируется как int равной 0, а затем компилятор запутывается ... (возможно, есть лучшее объяснение, но я не могу думать об этом). 1003 *

Использование% f для обеих переменных выводит 1.000000 для обеих переменных для меня.

Вы можете найти список символов преобразования в нижней части этой страницы:

http://www.exforsys.com/tutorials/c-language/managing-input-and-output-operations-in-c.html

...