преобразование типов в c - PullRequest
2 голосов
/ 17 января 2012
int main()
{
   int x,y;
   int z;
   char s='a';
   x=10;y=4;
   z = x/y;
   printf("%d\n",s); //97
   printf("%f",z); //some odd sequence
   return 0;

}

в приведенном выше фрагменте кода символы s автоматически преобразуются в int при печати из-за типа int в управляющей строке, но во втором случае преобразование int в float не происходит. Почему так?

Ответы [ 4 ]

7 голосов
/ 17 января 2012

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

Строка формата даже не просматривается компилятором: это просто аргумент некоторой функции. Что ж, действительно полезный компилятор может знать о printf() и может смотреть на строку формата, но только чтобы предупредить вас об ошибках, которые вы могли допустить. Фактически, gcc делает именно это:

t.c:9: warning: format ‘%f’ expects type ‘double’, but argument 2 has type ‘int’

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

3 голосов
/ 17 января 2012

Функции с переменным числом аргументов следуют правилу продвижения аргументов по умолчанию .Правила целочисленного продвижения применяются к аргументам целочисленных типов, а float аргументы преобразуются в double.

printf("%d\n",s);

s - это символ и преобразуется в int.

printf("%f",z);

z уже является int, поэтому преобразование z

не выполняется. Теперь спецификатор преобразования f ожидает double, но тип объекта после продвижение аргумента по умолчанию - это int, так что это неопределенное поведение.

Вот что говорит C об аргументах библиотечных функций с переменным числом аргументов

(C99, 7.4.1p1) "Если аргумент функции имеет [...] тип (после продвижения), которого не ожидает функция с переменным числом аргументов, поведение не определено."

0 голосов
/ 17 января 2012

из-за типа int в управляющей строке

Это неверно.Он конвертируется, потому что более короткие типы int переводятся в int процессом var_args.Типы Int не преобразуются в типы с плавающей точкой, поскольку препроцессор va / не знает, какие форматы ожидаются.

0 голосов
/ 17 января 2012

char - это , а не , которое переводится в int из-за управляющей строки.char работает как int, потому что все данные размером менее 4 байт при передаче в printf увеличиваются до 4 байтов, что является размером int, из-за соглашения о вызовах cdecl для функций с переменными числами(суть в том, что следующие данные будут выровнены по 4-байтовой границе в стеке).

printf не является типобезопасным и не знает, какие данные вы действительно передаетеЭто;он слепо считывает управляющую строку и извлекает определенное количество байтов из стека на основе найденных последовательностей и интерпретирует этот набор байтов как тип данных, соответствующий управляющей последовательности.Он не выполняет никаких преобразований, и причина, по которой вы получаете некоторую странную распечатку, состоит в том, что биты int интерпретируются как биты float.

...