bool look_up( int *, int );
double calc( double );
int count( const string , char );
Date calendar( const char );
void sum( vectorint, int );
Однако функция или встроенный массив не могут быть типом возвращаемого значения. Следующий пример ошибочен:
// массив не может быть типом возвращаемого значения
int[10] foo_bar();
Но можно вернуть указатель на первый элемент массива:
// правильно: указатель на первый элемент массива
int *foo_bar();
(Размер массива должен быть известен вызывающей программе.)
Функция может возвращать типы классов, в частности контейнеры. Например:
// правильно: возвращается список символов
listchar foo_bar();
(Этот подход не очень эффективен. Обсуждение типа возвращаемого значения см. в разделе 7.4.)
Тип возвращаемого функцией значения должен быть явно указан. Приведенный ниже код вызывает ошибку компиляции:
// ошибка: пропущен тип возвращаемого значения
const is_equa1( vectorint vl, vectorint v2 );
В предыдущих версиях С++ в подобных случаях считалось, что функция возвращает значение типа int. Стандарт С++ отменил это соглашение. Правильное объявление is_equal() выглядит так:
// правильно: тип возвращаемого значения указан
const bool is_equa1( vectorint vl, vectorint v2 );
7.2.2. Список параметров функции
Список параметров не может быть опущен. Функция, которая не требует параметров, должна иметь пустой список либо список, состоящий из одного ключевого слова void. Например, следующие объявления эквивалентны:
int fork();
int fork( void );
Такой список состоит из названий типов, разделенных запятыми. После имени типа может находиться имя параметра, хотя это и необязательно. В списке параметров не разрешается использовать сокращенную запись, соотнося одно имя типа с несколькими параметрами:
int manip( int vl, v2 ); // ошибка
int manip( int vl, int v2 ); // правильно
Имена параметров не могут повторяться. Имена, фигурирующие в определении функции, можно и даже нужно использовать в ее теле. В объявлении же функции они не обязательны и служат средством документирования ее интерфейса. Например:
void print( int *array, int size );
Имена параметров в объявлении и в определении одной и той же функции не обязаны совпадать. Однако употребление разных имен может запутать пользователя.
С++ допускает сосуществование двух или более функций, имеющих одно и то же имя, но разные списки параметров. Такие функции называются перегруженными. О списке параметров в этом случае говорят как о сигнатуре функции, поскольку именно он используется различения разных версий одноименных функций. Имя и сигнатура однозначно идентифицируют версию. (Перегруженные функции подробно обсуждаются в главе 9.)
7.2.3. Проверка типов формальных параметров
Функция gcd() объявлена следующим образом:
int gcd( int, int );
Объявление говорит о том, что имеется два параметра типа int. Список формальных параметров предоставляет компилятору информацию, с помощью которой тот может проверить типы передаваемых функции фактических аргументов.
Что будет, если попытаться вызвать функцию gcd() с аргументами типа char*?
cd( "hello", "world" );
А если передать этой функции не два аргумента, а только один? Или больше двух? Что случится, если потеряется запятая между числами 24 и 312?
gcd( 24312 );
Единственное разумное поведение компилятора – сообщение об ошибке, поскольку попытка выполнить такую программу чревата весьма серьезными последствиями. С++ действительно не пропустит подобные вызовы. Текст сообщения будет выглядеть примерно так:
// gcd( "hello", "world" )
error: invalid argument types ( const char *, const char * ) --
expecting ( int, int )
ошибка: неверные типы аргументов ( const char *, const char * ) --
ожидается ( int, int )
// gcd( 24312 )
error: missing value for second argument
ошибка: пропущено значение второго аргумента
А если вызвать эту функцию с аргументами типа double? Должен ли этот вызов расцениваться как ошибочный?
gcd( 3.14, 6.29 );