Программирование на C и C++

Онлайн справочник программиста на C и C++

Функции, возвращающие нецелые значения

Когда не объявляется возвращаемое функцией значение, то предполагается, что она возвращает int (хотя это может измениться в будущем). Для большинства функций это вполне приемлемо. Тем не менее, когда функция возвращает различные типы данных, следует использовать нижеприведенный двушаговый процесс:

  1. Функция должна иметь явно определенный тип возвращаемого значения.
  2. Компилятор должен знать о типе возвращаемого функцией значения перед первым ее вызовом.

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

Функции могут возвращать любой допустимый тип данных. Метод объявления аналогичен методу для переменных: спецификатор типа должен предшествовать имени функции. Спецификатор типа сообщает компилятору, какой тип данных возвращает функция, Эта информация критична, если программа должна работать корректно, поскольку различные типы данных имеют различные размеры и различное внутреннее представление.

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

Обычным способом информирования компилятора о типе возвращаемого значения является  использование предварительного описания. Такой способ объявляет тип возвращаемого значения, но на самом деле не определяет действие функции. Определение функции происходит где-то в другом месте программы.

Имеется два способа создания предварительного описания. Первый состоит в использовании стандарта С, который был до ANSI и на сегодняшний момент устарел. Второй состоит в использовании прототипа функции, прототипы добавляются стандартом ANSI С. Старый способ по-прежнему можно применять для поддержания совместимости со старым кодом, но лучше использовать новый способ.

ЗАМЕТКА: С++ не поддерживает старый метод объявления функций. Вместо этого С++ требует прототипы. Материал, присутствующий в данном разделе, применим только к языку С.

Хотя информация в данном разделе устарела, в нем коротко описывается старый способ объявления функций, поскольку существует много старых программ, использующих его. Старый способ просто объявляет возвращаемое значение и имя функции в начале программы. Например, для того, чтобы сообщить С, что функция myfunc() возвращает значение типа double, следует поместить следующую строку в начале программы:

double myfunc();

Даже если myfunc() имеет параметры, в данном старом методе в скобках ничего не указывается. Когда компилятор читает данную строчку, он знает, что myfunc() возвращает значение типа double и, следовательно, генерирует правильный код возврата. Например, ниже показана корректно работающая (хотя и старая) программа:

/* Старый стиль программы будут приводить к выдаче предупреждения при компиляции * /

#include <stdio.h>
#include <math.h>
double myfunc(); /* предварительное объявление myfunc() */
int main(void)
{
printf ("%lf", myfunc (10.0));
return 0;
}

double myfunc(double x)
{
return sqrt (x) * 2.0; /* возвращает квадратный корень x, умноженный на 2 */
}

Как можно видеть, хотя myfunc() имеет один параметр, старый способ объявления ничего об этом не говорит.

В то время как в стандартах как Borland С++, так и ANSI С допустимо использование предварительного объявления функции, что подразумевает информирование компилятора о типе возвращаемого функцией значения, лучше не использовать данный способ в новом коде. Причина в том, что прототип функции, добавленный комитетом ANSI, предоставляет гораздо лучшую альтернативу. И что более важно, использование прототипов необходимо в программах на С++.