- •Лабораторная работа 3 Функции
- •Примеры вызовов функций
- •Демонстрация функции без аргументов и не возвращающей значения
- •Демонстрация функции, определенной перед ее вызовом
- •Демонстрация функции с аргументами и не возвращающей значения
- •Демонстрация использования глобальных переменных при обмене данными между функциями
- •Демонстрация использования в функции локальных статических переменных
- •Передача в функцию в качестве параметра переменных разных типов Функция вычисления минимального расстояния между точками плоскости
- •Функция вычисления факториала
- •Функция вычисления хn через умножение
- •Функция определения максимального и минимального из двух чисел
- •Функция с параметром перечисляемого типа
- •Функция, выделяющая целую и дробную части вещественного числа
- •Функция, возвращающая ссылку как результат своей работы
- •Демонстрация inline-функций
- •Демонстрация функции с параметрами по умолчанию
- •Перегрузка функций
- •Перегрузка функций с равным числом аргументов
- •Перегрузка функций с разным числом аргументов
- •Шаблоны семейства функций
- •Рекурсивные функции
- •Рекурсивная функция вычисления факториала
- •Рекурсивная функция вывода на печать символов строки в обратном порядке
- •Рекурсивная функция печати числа в виде строки символов
- •Вычисление нод через итерации и через рекурсивную функцию
- •Вычисление интеграла по методу правых прямоугольников
- •Использование одинаковых вызовов функции для вычисления интеграла разными методами и для разных функций
- •Использование при вычислении интеграла многофайловой компиляции
- •Вычисление корня нелинейного уравнения
- •Правила оформления и вызова функций
- •Элементы оптимизации работы с функциями
Перегрузка функций с разным числом аргументов
А теперь рассмотрим пример перегрузки функций, имеющих разное количество параметров. Функции выполняют вывод на экран символа (заданного в виде аргумента или определенного в функции) некоторое количество раз (заданное в качестве аргумента или определенное в функции):
void repchar(); //прототип функции для вывода символа ‘*’ 45 раз
void repchar(char); //прототип функции для вывода символа-аргумента 45 раз
void repchar(char, int); //прототип функции для вывода символа-аргумента
// заданное через второй аргумент количество раз
//--------------------------------------------------------------
int main()
{
repchar(); //вызов функции для вывода символа ‘*’ 45 раз
repchar('='); //вызов функции для вывода символа ‘=’ 45 раз
repchar('+', 30); //вызов функции для вывода символа ‘+’ 30 раз
_getch();
return 0;
}
//--------------------------------------------------------------
void repchar() //определение функции вывода символа ‘*’ 45 раз
{
for(int j=0; j<45; j++)
cout << '*';
cout << endl;
}
//--------------------------------------------------------------
void repchar(char ch) //определение функции вывода символа-аргумента 45 раз
{
for(int j=0; j<45; j++)
cout << ch;
cout << endl;
}
//--------------------------------------------------------------
void repchar(char ch, int n) //определение функции вывода символа-аргумента заданное
{ //через второй аргумент количество раз
for(int j=0; j<n; j++)
cout << ch;
cout << endl;
}
Результат работы:
*********************************************
=============================================
++++++++++++++++++++++++++++++
Шаблоны семейства функций
Подготовку перегружаемых функций помогают автоматизировать шаблоны. Шаблон семейства функций определяется один раз, но это определение параметризуется. Для этого используется список параметров шаблона (в качестве параметра на этапе компиляции передается конкретный тип данных).
Шаблон семейства функций состоит из двух частей: заголовка шаблона (template <список параметров шаблона>) и обычного определения функции (заголовок и тело функции), в котором тип возвращаемого значения и/или типы параметров обозначаются именами параметров шаблона, введенных в его заголовке. Имена параметров шаблона могут использоваться и в теле определения функции для обозначения типов локальных объектов.
Формат простейшей функции-шаблона:
template <class type> заголовок функции
{ //тело функции
}
где вместо слова type может использоваться произвольное имя.
Определим шаблон семейства функций, вычисляющих абсолютное значение числовых величин разных типов:
//--------------------------------------------------------------
template <class T> //шаблон семейства функций T abs(T n)
T abs(T n)
{
return (n < 0) ? -n : n;
}
//--------------------------------------------------------------
int main()
{
int i1 = 5; //инииализация переменных разных типов и знаков
int i2 = -6;
long l1 = 70000L;
long l2 = -80000L;
double d1 = 9.95;
double d2 = -10.15;
//вызовы функций
cout << "\nabs(" << i1 << ")=" << abs(i1); //abs(int)
cout << "\nabs(" << i2 << ")=" << abs(i2); //abs(int)
cout << "\nabs(" << l1 << ")=" << abs(l1); //abs(long)
cout << "\nabs(" << l2 << ")=" << abs(l2); //abs(long)
cout << "\nabs(" << d1 << ")=" << abs(d1); //abs(double)
cout << "\nabs(" << d2 << ")=" << abs(d2); //abs(double)
cout << endl;
_getch();
return 0;
}
Определим шаблон семейства функций для обмена значений двух передаваемых им параметров:
template <class T> void swap(T* x, T* y) {T z=*x; *x=*y; *y=z;}
При определении переменных long k=4, d=8; и вызове swap(&k, &d);
будет сформировано определение
void swap(long* x, long* y) {long z=*x; *x=*y; *y=z;}
При определении переменных double a=2.44, b=66.3; и вызове swap(&a, &b);
будет сформировано определение
void swap(double* x, double* y) {double z=*x; *x=*y; *y=z;}
Определим шаблон семейства функций для поиска минимального из трех значений, причем функция возвращает элемент с минимальным значением:
template <class T>
T min3(T x, T y, T z)
{T min =x;
if (y<min) min = y;
if (z<min) min = z;
return min;
}
int main()
{int a=2, b=5, c=-5;
cout << min3(a*c, b, c) << endl; //-10
cout << min3(0.03*a, 10.0, 5.0) << endl; //0.06
_getch();
return 0;
}
Если все 3 аргумента будут одного типа, компилятор создаст нужную функцию, если нет – то сообщение об ошибке.
Имя параметра шаблона, например N (template <class N>), видимо во всем определении и скрывает другие определения того же идентификатора в области, глобальной по отношению к данному шаблону; для доступа к ним используется операция изменения области видимости:
int N=0; //глобальная переменная N
template <class N> //прототип шаблона
N maxx (N x, N y); //идентификаторы параметров в прототипе шаблона не опускаются
int main()
{int a=12, b=42;
maxx (a, b);
cout << a << " " << b << endl;
float z=66.3f, f=222.4f;
maxx (z, f);
cout << z << " " << f << endl;
_getch();
return 0;
}
template <class N> //определение шаблона
N maxx (N x, N y)
{N a = x;
cout << "\n N=" << ++ ::N << endl;
if (a<y) a=y;
return a;
}