Общий вид описания пользовательской функции в С++ имеет вид:
тип_возвращаемого_значения имя( список_аргументов )
/** тело_функции;
return выражение; **/
В качестве типов возвращаемых величин могут использоваться char, int, float, double, их производные, указатели и ссылки.
В качестве типа_возвращаемого_значения можно указывать ключевое слово void, обозначающее, что функция не возвращает никакого значения в вызвавшую ее программу (аналог процедур в Паскале).
Для контроля правильности обмена данных между функциями целесообразно использование механизма, опирающегося на шаблоны, или прототипы функций. Форма прототипа соответствует формальному определению заголовка функции, не содержит тела функции и заканчивается символами ;
float hypot(float x, float y);
- функция вычисляет и возвращает длину гипотенузы прямоугольного треугольника по известным длинам его катетов x и y.
После объявления прототипа функция должна быть описана ниже.
Идентификатор переменной в списке формальных аргументов не является обязательным и может быть опущен:
float hypot(float, float);
В прототипе также допускается задание аргументов по умолчанию:
float hypot(float=1, float=1);
Прототип функции можно описать внутри основной функции.
Анонимные функции не имеют индентификатора, по которому к ним можно обращаться.
[](int x, int y)/** return x + y; **/
Некоторые функции в языке C++ можно определить с использованием специального служебного слова inline.
Подобное описание позволяет определить функцию как встраиваемую, то есть подставляемую в текст программы при компиляции в местах обращения к этой функции.
Пример:
#include <iostream.h>
float inline qub(float x) /** return x*x*x;**/
void main()
/** float z=2; z=qub(z); cout<<z; cin.get(); **/
Функция может производить не более одного значения. Для обхода этого правила необходимо выводить измененные значения параметров из функции (в Паскале для этого использовалось слово var перед параметром).
В С++ есть несколько методов обмена значениями параметров, использующих принципы адресной арифметики С++. Рассмотрим один из этих методов, основанный на использовании ссылок:
#include <iostream.h>
void ff(float x, float &y) /** x=x+1; y=y*2;**/ // вместо параметра y
// используется ссылка, то есть аналог переменной
Рекурсивной будем называть функцию, при определении которой происходит обращение к ней самой.
В качестве примера рассмотрим функцию вычисления факториала:
void main () #include<iostream.h>
int factorial(int n) /** return (n>1)?n*factorial(n-1):1;**/
/** int n;
cout<<"Vvedite n: "; cin>>n;
cout<<n<<"!="<<factorial(n);
cin.get();**/
В качестве результата работы функции может быть указатель на массив, создаваемый в этой функции. Изменим предыдущий пример: количество элементов массивов будем рассчитывать программно; функция возвратит указатель на созданный массив.
#include <iostream.h>
int *max_vect(int n, int *x, int *y)
/** int *z = new int[n]; //выделение памяти для массива
for (int i=0;i<n;i++) z[i]=x[i]>y[i]?x[i]:y[i];
return z;**/
void main()
/** int a[ ]=/**1,2,3,4,5,6,7**/; int b[ ]=/**7,6,5,4,3,2,1**/;
int kc=sizeof(a)/sizeof(a[0]); //вычисление размера массива
int *c; //указатель на результирующий массив
c=max_vect(kc,a,b); //создание массива
for (int i=0;i<kc;i++) cout<< " " << c[i];
delete [ ]c; cin.get();**/
Перегрузка операций позволяет иметь различные версии одинаково названной функции или процедуры с различными параметрами.
Шаблоны функций, своими словами,— это инструкции, согласно которым создаются локальные версии шаблонированной функции для определенного набора параметров и типов данных.
template <typename T>
void printArray(const T * array, int count)
/**
for (int ix = 0; ix < count; ix++)
cout << array[ix] << " ";
cout << endl;
**/ // конец шаблона функции printArray
Адрес функции является входной точкой функции. Поэтому указатель на функцию может использоваться для вызова функции
Указатели на функции задаются следующим образом:
void f() /** **/
void (*pf)() = &f;
pf();
В этом коде f - некоторая функция.
Во второй строчке определяется переменная pf, которая является указателем на функцию, которая ничего не возвращает и не принимает ни одного аргумента. В определении pf ей присваивается адрес функции f.
В третьей строке мы вызываем функцию по указатели pf(в данном случае будет вызвана функция f).
Так же может создаваться массив указателей на функции
Пример:
void enter(void), del(void), review(void), quit(void); int menu(void);
void (*options[])(void) = /**
enter,
del,
review,
quit
**/;// Здесь, при вызове указателя функции, в теле программы, (*options[i])(void) будет вызвана i-я функция.(Для i=4 будет вызвана функция “quit(void)” параметр передается из options)