Какова цель требования спецификации типа данных возвращаемого значения в определении функции или прототипе? Приведение типов? - PullRequest
0 голосов
/ 21 июня 2020

Рассмотрим следующий фрагмент кода:

#include<stdio.h>

int demo_function(float a);

int main(void) 
{
  
  int b;
  float fraction_number = 3.15f;
  b = demo_function(fraction_number);
  printf("The number returned is %d", b);
  return 0;
}

int demo_function(float a)
{
  float c;
  c = a;
  printf("The number passed is %.2f \n", c);
  return c;
}

Результат:

The number passed is 3.15

The number returned is 3

Из этого маленького тестовый код выглядит как фактическая цель записи int, поскольку тип данных возвращаемого значения demo_function - приведение типов .

Во-первых, это правильная интерпретация того, что происходит?

Во-вторых, зачем компилятору действительно нужна эта информация? (Или, возможно, лучше спросить: «Как компилятор использует эту информацию?»). В частности, если компилятор видит, что переменная b объявлена ​​как int, зачем ему явно знать, что возвращаемое значение имеет тип int?

Если мы в конечном итоге сохраняем возвращаемое значение переменной c в b, какие проблемы возникнут, если компилятор НЕ требует явного упоминания о том, что возвращаемое значение имеет тип int? Произойдет ли потеря информации, поскольку переменная float c пытается поместить сплющенный в меньшую выделенную память int b переменную?

Спасибо!

1 Ответ

2 голосов
/ 21 июня 2020

На практике компилятор должен знать, какой тип возвращает функция, потому что ему нужно знать, как интерпретировать биты, возвращаемые функцией, и ему нужно знать, где эти биты.

Предположим, что когда функция возвращает, регистр, используемый для возвращаемого значения, содержит 0x80. Если функция должна возвращать 8-битное unsigned char, то возвращаемое значение - 128. Если функция должна возвращать 8-битное дополнение до двух signed char, то возвращаемое значение - -128. Знание типа необходимо для понимания интерпретации битов.

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

На более абстрактном уровне компилятору необходимо знать тип возвращаемого значения функция, чтобы она могла интерпретировать выражение, в котором появляется вызов функции. Учтите, что в C выражение 5 / 4 выполняет целочисленное деление с усечением и дает 1, а выражение 5. / 4 выполняет деление с плавающей запятой и дает 1,25 . Итак, в выражении f(x) / 4 компилятор должен знать, какой тип f возвращает, чтобы он знал, выполнять ли целочисленное деление или деление с плавающей запятой.

Для другого примера предположим, что f возвращает указатель, и программа использует y = *f(x). Чтобы выполнить этот код, компилятор должен взять значение, возвращаемое f, и использовать его как адрес для извлечения чего-либо из памяти. Но что он приносит? Указывает ли адрес на однобайтовую char, восьмибайтовую double или 100-байтовую структуру? Компилятору необходимо знать тип указателя, возвращаемого f, чтобы он знал, на какой тип объекта он указывает.

Из этого небольшого тестового кода кажется, что реальная цель записи int в качестве типа данных возвращаемого значения demo_function - это приведение типов .

Основная цель описана выше. Тот факт, что значение в операторе return преобразуется в тип возвращаемого значения функции, является вторичным эффектом; это просто удобство языка, а не необходимый эффект. (В неявном преобразовании нет необходимости, потому что мы могли бы повлиять на преобразование, указав его явно.)

Также обратите внимание, что cast является явным оператором. Это не операция. Например, + и * - операторы; это вещи, которые появляются в исходном коде и говорят, что мы хотим выполнить определенные операции. Фактические операции - это сложение и умножение. Точно так же приведение - это имя типа в круглых скобках; это некоторый текст, который появляется в исходном коде, который указывает, что мы хотим выполнить преобразование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...