Функции в С++. Перегрузка функций. (Лекция 3)

Содержание

Слайд 2

Структурирование кода

Функция представляет собой именованную группу операторов, которые выполняют определенную задачу. Эта

Структурирование кода Функция представляет собой именованную группу операторов, которые выполняют определенную задачу.
группа операторов задействуется путем вызова функции.
Основные причины использования функций:
1) стремление сократить размер кода,
2) стремление упростить кодирование часто повторяющихся задач.

Одним из способов структурирования программного кода является использование процедур и функций (процедурное программирование).

Слайд 3

Методы использования функций

Часто выделяют следующие этапы создания функций и работы с ними:

Методы использования функций Часто выделяют следующие этапы создания функций и работы с
объявление функции (прототип)
определение функции
вызов (выполнение функции)

Слайд 4

1) Объявление (прототип)

не содержит тела функции, но указывает ее имя, арность, типы

1) Объявление (прототип) не содержит тела функции, но указывает ее имя, арность,
аргументов и возвращаемый тип данных,
представляет собой описание интерфейса функции (ее сигнатуру).
Пример
int func1(int k);

Слайд 5

2) Определение

содержит сигнатуру функции,
содержит тело функции – то есть код, выполняемый

2) Определение содержит сигнатуру функции, содержит тело функции – то есть код,
при вызове.
int func1(int k)
{
int n = 1;
for(int i = 1; i <= k; i++)
n *= i;
return n;
}

Слайд 6

3) Вызов функции

внешне похож на прототип,
инициирует выполнение функции.
int F;
...

3) Вызов функции внешне похож на прототип, инициирует выполнение функции. int F;
F = func1(5);

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

Слайд 7

Передача программного управления при вызове функции

Передача программного управления при вызове функции

Слайд 8

Использование стека вызовов

Стек вызовов (call stack) — область памяти, используемая при вызовах

Использование стека вызовов Стек вызовов (call stack) — область памяти, используемая при
функций.
В стек помещаются:
1) фактические параметры,
2) адрес возврата из функции,
3) локальные переменные,
4) значения регистров.

Слайд 9

Ссылки

Ссылка – особый тип данных, являющийся скрытой формой указателя, который при использовании

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

тип &имя_ссылки = имя переменной;

Слайд 10

Пример использования ссылки
int main(int argc, char* argv[])
{
int value =

Пример использования ссылки int main(int argc, char* argv[]) { int value =
15;
int &reference = value; // ссылка
cout << "value = " << value << endl;
cout << "reference = " << reference << endl;
reference+=15; // изменяем
cout << "value = " << value << endl;
cout << "reference = " << reference << endl;
system("pause");
return 0;
}

Слайд 11

Передача аргументов в функцию

В языке С++ существует несколько способов передачи аргументов внутрь

Передача аргументов в функцию В языке С++ существует несколько способов передачи аргументов
вызываемой функции
Передача по значению. В стеке создается копия передаваемого значения, и функция получает доступ к этой копии.
Передача по адресу. Функции передается указатель на область памяти, где располагается аргумент. Используя операцию разыменования, функция получает прямой доступ к значению.
Передача по ссылке. В функцию передается ссылка на аргумент (фактически, его адрес). Для доступа к значению аргумента разыменование не требуется.

Слайд 12

void f(int x) // по значению
{
cout << x;

void f(int x) // по значению { cout x = 1; cout
x = 1;
cout << x;
}
void g(int* x) // по адресу
{
cout << *x;
*x = 2;
cout << *x;
}
void h(int& x) // по ссылке
{
cout << x;
x = 3;
cout << x;
}

int main()
{
int x = 0;
f(x);
g(&x);
h(x);
return 0;
}

01 02 23

Слайд 13

В функцию могут передаваться не только переменные стандартных типов (int, float, char,

В функцию могут передаваться не только переменные стандартных типов (int, float, char,
...), но и структурные переменные. В С++ структура может быть передана в функцию любым из трех способов - по значению, по адресу, по ссылке.
#include
using namespace std;
struct Distance
{
int feet;
float inches;
};
void display(Distance dd)
{
cout << dd.feet << "\'-" << dd.inches << "\"";
}

Слайд 14


void scale(Distance& dd, float f)
{
float inches = (dd.feet*12

void scale(Distance& dd, float f) { float inches = (dd.feet*12 + dd.inches)
+ dd.inches) * f;
dd.feet = static_cast(inches / 12);
dd.inches = inches - dd.feet * 12;
}
int main()
{
...
Distance d1 = {12, 6.5};
Distance d2 = {10, 5.5};
scale(d1, 0.5);
scale(d2, 0.25);
display(d1);
display(d2);
...
return 0;
}

Слайд 15

#include "mscon.h"
struct circle
{
int x, y; // центр

#include "mscon.h" struct circle { int x, y; // центр окружности int
окружности
int radius; // радиус
color fillcolor; // цвет
fstyle fillstyle; // стиль заполнения
};
void circ_draw(circle c)
{
set_color(c.fillcolor);
set_fill_style(c.fillstyle);
draw_circle(c.x, c.y, c.radius);
}
//... (окончание)

Пример приложения. Прорисовка окружностей в текстовом режиме

Слайд 16

// ... (начало)
int main()
{
init_graphics();
circle c1 = {15,

// ... (начало) int main() { init_graphics(); circle c1 = {15, 7,
7, 5, cBLUE, X_FILL};
circle c2 = {41, 12, 7, cRED, O_FILL};
circle c3 = {65, 18, 4, cGREEN, MEDIUM_FILL};
circ_draw(c1);
circ_draw(c2);
circ_draw(c3);
set_cursor_pos(1, 25);
return 0;
}

Слайд 17

Результата работы приложения

Результата работы приложения

Слайд 18

Значение, возвращаемое функцией

Функция возвращает результат своей работы в вызывающую программу с помощью

Значение, возвращаемое функцией Функция возвращает результат своей работы в вызывающую программу с
оператора return.
Кроме переменных стандартных типов (int, float, char, ...) в языке С++ функция может возвращать значения структурного типа.

Слайд 19

Distance add(Distance dd1, Distance dd2)
{
Distance dd3;
dd3.inches = dd1.inches + dd2.inches;

Distance add(Distance dd1, Distance dd2) { Distance dd3; dd3.inches = dd1.inches +

dd3.feet = 0;
if(dd3.inches >= 12.0)
{
dd3.inches -= 12.0;
dd3.feet++;
}
dd3.feet += dd1.feet + dd2.feet;
return dd3;
}

Пример. Структура как возвращаемое значение

Слайд 20

Перегрузка функций

Перегрузка функций в языке С++ означает использование нескольких вариантов функции с

Перегрузка функций Перегрузка функций в языке С++ означает использование нескольких вариантов функции
одним и тем же именем, но с разным числом аргументов или разными типами аргументов.
При вызове перегруженной функции, выбор ее конкретного варианта происходит на основе анализа количества и типа аргументов. Такой подход получил называние статического полиморфизма.
На этапе трансляции программы происходит контроль одноимённых функций, чтобы они различались по сигнатуре.

Слайд 21

// объем куба
int volume(int s)
{
return(s*s*s);
}
// объем цилиндра

// объем куба int volume(int s) { return(s*s*s); } // объем цилиндра
double volume(double r, int h)
{
return(3.14*r*r*h);
}
// объем параллелепипеда
long volume(long l, int b, int h)
{
return(l*b*h);
}

Пример. Перегрузка функции расчета объема тела.
int main()
{
cout << volume(10);
cout << volume(2.5,8);
cout << volume(9,5,4);
return 0;
}

Слайд 22

Константные аргументы функции

Ссылки на аргументы функции используются не только в случаях, когда

Константные аргументы функции Ссылки на аргументы функции используются не только в случаях,
необходимо менять значения аргументов. Часто ссылочный механизм передачи применяется для повышения скорости работы программы (пример - передача через стек крупных структурных объектов с большим количеством полей).
В случае, если ссылка используется только для повышения эффективности, свободный доступ к значению аргумента может быть ограничен с помощью модификатора const.

Слайд 23

void func(int& a, const int& b)
{
a = 107; // нет

void func(int& a, const int& b) { a = 107; // нет
ошибки
b = 111; // ошибка: попытка изменения
} // константного аргумента
int main()
{
int alpha = 7;
int beta = 11;
func(alpha, beta);
return 0;
}

Пример. Использование константной ссылки в качестве аргумента функции

Слайд 24

Создание библиотечного модуля

Пример: модуль арифметических функций.
Заголовочный файл библиотеки «mathfuncs.h»
#ifdef MATHFUNCS_H
#define

Создание библиотечного модуля Пример: модуль арифметических функций. Заголовочный файл библиотеки «mathfuncs.h» #ifdef
MATHFUNCS_H
namespace mathspace
{
double add(double a, double b);
double subtract(double a, double b);
double multiply(double a, double b);
double divide(double a, double b);
}
#endif

Слайд 25

Файл реализации библиотечных функций «mathfuncs.cpp»
#include "mathfuncs.h"
#include
namespace mathspace
{
double add(double a,

Файл реализации библиотечных функций «mathfuncs.cpp» #include "mathfuncs.h" #include namespace mathspace { double
double b)
{
return a + b;
}
double subtract(double a, double b)
{
return a - b;
}
// ... (продолжение)

Слайд 26

//... (начало)
double multiply(double a, double b)
{
return a * b;

//... (начало) double multiply(double a, double b) { return a * b;
}
double divide(double a, double b)
{
if (b == 0)
{
throw std::invalid_argument("b = 0!");
}
return a / b;
}
}