Как можно приписать double к int даже в этом случае? - PullRequest
1 голос
/ 16 октября 2019

Я только начал изучать C, и у меня возникают проблемы с пониманием, почему следующий код вообще работает:

void convertMyNumber (float myValue) {
    int myNewValue = floor(myValue * 100);
    printf("%d", myNewValue);
}

Глядя на документацию по math.h, утверждается, что floor()Функция принимает double в качестве аргумента, а также возвращает double. Пока все отлично, я просто запустил приведенный выше код и набрал 576.73 в качестве значения для переменной myValue. Удивительно (для меня), он напечатал ровно 57673 на экране, и мне трудно понять, как возможно, что он смог приписать возвращаемое значение функции floor (a double) до int myNewValue.

Ответы [ 3 ]

2 голосов
/ 16 октября 2019

Эта строка int myNewValue = floor(myValue * 100); содержит не менее 3 неявных преобразований.

  • В myValue * 100 целочисленная константа 100 имеет тип int. Неявное преобразование, известное как «обычные арифметические преобразования» , преобразует операнд int в float. Умножение выполняется на float, а результирующий тип - float. См. Неявные правила продвижения типов .

  • Результат float, полученный в результате предыдущего вычисления, преобразуется в тип операнда функции. Параметры функции неявно преобразуются «как при присваивании», преобразуя переданный аргумент в тип параметра, в этом случае double.

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

Так вот почему это работает, но полагаться на неявные преобразованиячасто это не очень хорошая идея, поскольку вероятность случайных ошибок велика.

0 голосов
/ 16 октября 2019

Как уже упоминалось в комментарии, вы видите неявное или, эквивалентно, автоматическое преобразование типов, которое выполняется компилятором. В приведенном ниже примере показано, как можно выполнить преобразование явно, также называемое «приведение типа».

#include <stdio.h>
#include <math.h>

void f_to_i(float f);

int main(int argc, char *argv)
{
  float fl = 576.73;
  f_to_i(fl);
}

void f_to_i(float f)
{
  int i;
  // Implicit Conversion
  i = floor(f * 100);
  printf("%d\n", i);
  i = 0;
  // Explicit Conversion
  i = (int)floor(f * 100);
  printf("%d\n", i);
}
0 голосов
/ 16 октября 2019

В присваивании значение правого операнда неявно преобразуется в тип левого операнда. Вот так floor(576.73 * 100) = 57673.0 стал 57673. C делает это, принимая двойное значение и игнорируя (обрезая) его дробную часть.

...