Приводит ли процесс возврата / преобразовывает требуемый тип к результату в соответствии со стандартом C, или это поддерживается только в определенных реализациях? - PullRequest
4 голосов
/ 11 августа 2010

Я заметил, что

float f; 
[..]
printf("%i\n", f);

не является разумным

, но

printf("%i\n", (int)f);

является

, но также

int func(float f) {
    return f;
}

в порядке

printf("%i\n", func(f));

Это преобразование / приведение, которое выполняется процессом возврата или функцией, поддерживаемой стандартом, или в идеале требуется

int func(float f) {
    return (int) f;
}

?

Ответы [ 2 ]

5 голосов
/ 11 августа 2010

Преобразование стандартное.Соответствующая часть стандарта ISO C99 находится в разделе 6.8.6.4, параграф 3:

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

Таким образом, он неявно преобразуется так же, как в этом присваивании:

float f = 3.0f;
int i;

i = f;

допустимые преобразования:

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

(Ваш пример соответствует первому - и int, и float являются арифметическими типами)

1 голос
/ 11 августа 2010

Обычно, когда выражение имеет определенный числовой тип, и его контекст ожидает другой числовой тип, соответствующее преобразование произойдет автоматически.Это применимо в таких случаях, как:

void f(float);
void g(long);
int i = 3;
f(i); /*function call, with a prototype in scope*/
g(i); /*ditto*/
double d = i; /*assignment*/

Этот принцип также применим к выражению return инструкция.

Этот принцип не применим к функциям с переменным числом, таким какprintf.Причина в том, что правильные преобразования зависят от строки формата, и компилятору не требуется анализировать строку формата;фактически, если формат не является строковым литералом, компилятор обычно не может его проанализировать.Таким образом, все приведения необходимы в следующем printf вызове:

int i = 3;
float f = 1.5;
printf("%ld %f %d\n", (long)i, (double)i, (int)f);

Однако из-за повышений (char и short повышаются до int, float повышается до double) и к тому факту, что %c ожидает int, в следующем printf вызове нет необходимости в приведениях:

char c = 'a';
float f = 1.5;
printf("%c %d %f", c, c, f);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...