2010-11-16 3 views
3

Что происходит здесь:Неявное преобразование в C?

printf("result = %d\n", 1); 
printf("result = %f\n", 1); 

выходы:

result = 1 
result = 0.000000 

Если я обеспечить тип этих переменных, прежде чем пытаться напечатать их, он отлично работает, конечно. Почему второй оператор печати не получает неявно преобразованного в 1.00000?

ответ

8

Во втором случае у вас есть несоответствие между вашей строкой формата и типом аргумента - поэтому результат не определен behavio (u) r.

+9

+1 для дополнительной буквы в «поведении». Us Brits используют его как резервное копирование в случае, если что-то неприятное происходит с «o». –

+1

@ Moo-Juice: Также, чтобы слово имело полный набор доступных гласных. – caf

+1

@caf: Почему я не могу найти y? =) – Arkku

2

Неопределенное поведение. ИНТ рассматривается как поплавок

+0

ITYM "a int обрабатывается как float". –

+0

спасибо, я исправил. –

+2

+1 для правильного написания. ;-) –

0

Интересно, по-видимому, это хорошо, если ваш пут «1,0»

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

+0

Компилятор не знает, какие типы ожидает функция. Это то, что делает вариационные функции очень лучными, чтобы ошибиться –

+0

@ Александр: обратите внимание, что некоторые компиляторы, например.gcc, ** do ** проверить строку формата для printf * et al * и может выдавать предупреждения для несоответствий в числе и/или типах аргументов. –

1

Короткий ответ: printf на самом деле не C++. Printf - это функция C, которая принимает список переменных аргументов и применяет предоставленные аргументы к строкам формата, типы, указанные в строке формата.

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

4

Причина, по которой 1 не преобразован в 1.0, состоит в том, что printf является «просто» функцией C с переменным числом аргументов, и только первый (обязательный) аргумент имеет указанный тип (const char *). Поэтому компилятор «не может» знать, что он должен преобразовывать «лишний» аргумент - он передается до. printf фактически считывает строку формата и определяет, что он должен получить число с плавающей запятой.

Теперь, правда, ваша строка формата является константой во время компиляции, поэтому компилятор может сделать особый случай из printf и предупреждают вас о некорректных аргументов (и, как уже упоминалось, некоторые компиляторы это сделать , по крайней мере, если вы попросите их). Но в общем случае он не может знать конкретные форматы, используемые произвольными функциями vararg, а также возможно построить строку формата сложными способами (например, во время выполнения).

В заключение, если вы хотите передать конкретный тип в качестве аргумента «переменная», вам необходимо отправить его.

+0

Обратите внимание, что для переменных аргументов 'char' и' short' повышаются до 'int', а' float' повышается до 'double'. – tomlogic

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