1. Модуль 1: Базовые понятия языка программирования С++
Темы лекции: Функции языка С++.
Практическое задание: Функции языка С++.
Тренер: Игорь Шкулипа, к.т.н.
C++ Базовый. Занятие 3
2. http://www.slideshare.net/IgorShkulipa 2
Функция
Функция - это группа операторов у которой есть имя, и которая может возвращать
значение. Функции позволяют разбить программу на небольшие части, каждая
из которых выполняет какую-то небольшую задачу.
[<класс памяти>] [<тип>] <имя функции> ([список формальных параметров])
{
<тело функции>
}
#include <iostream>
#include <math.h>
using namespace std;
void main()
{
double a, b, c, p;
cin>>a>>b>>c;
p=(a+b+c)/2;
s=sqrt(p*(p-a)*(p-b)*(p-c));
cout<<“Square=”<<s<<“n”;
}
#include <iostream>
#include <math.h>
using namespace std;
void main()
{
double a, b, c, p;
cin>>a>>b>>c;
cout<<“Square=”<<square(a,b,c)<<“n”;
}
double square(double a, double b, double c)
{
double p=(a+b+c)/2;
return sqrt(p*(p-a)*(p-b)*(p-c));
}
3. http://www.slideshare.net/IgorShkulipa 3
Определение функции
Определение функции должно располагаться в глобальной области
видимости, до начала функции main. Функции, которые используются
в других функциях должны быть определены перед функциями,
которые их используют.
#include <iostream>
using namespace std;
int sum (int a, int b)
{
return a+b;
}
void main()
{
cout<<“1+1=”<<sum(1,1)<<“n”;
}
#include <iostream>
using namespace std;
int sum (int a, int b)
void main()
{
cout<<“1+1=”<<sum(1,1)<<“n”;
}
int sum (int a, int b)
{
return a+b;
}
Идентификатор (имя)
функции задаётся точно
также, как и любой другой
идентификатор.
4. http://www.slideshare.net/IgorShkulipa 4
Тип возвращаемого значения
Почти все функции должны возвращать значения. Тип этого значения
указывается в заголовке перед именем функции.
int int_function();
float float_function();
char char_function();
Если функция не возвращает значение, ей должен быть присвоен тип
void.
void void_function();
Если тип функции явно не указан, то считается, что она имеет тип int.
int_function(); ←➔ int int_function();
Для возвращения значения функции служит оператор return;
return 0;
5. http://www.slideshare.net/IgorShkulipa 5
Тело функции, вызов функции, вызывающее окружение
Тело функции – это, непосредственно действия, которые эта функция
выполняет. Тело функции располагается сразу под заголовком и
заключено в фигурные скобки. В теле функции может содержаться
сколько угодно операторов. Если функция имеет тип не void, то в ней
обязательно должен присутствовать оператор return.
int sum (int a, int b)
{
int c;
c = a + b;
return c;
}
int sum (int a, int b)
{
return a+b;
}
После того как создано определение функции, её можно вызвать. Для
вызова функции существует оператор вызова функции.
<имя функции> ([<параметры>])
cout<<“1+1=”<<sum(1,1)<<“n”;
То место, откуда вызывается функция, называется вызывающим
окружением. Вызывающим окружением функции sum является
функция main, а вызывающим окружением функции main является
отладчик или операционная система.
6. http://www.slideshare.net/IgorShkulipa 6
Прототипы функций
Для того, чтобы функция могла быть вызвана, она должна быть
объявлена перед тем местом, где она вызывается. Бывают случаи,
когда необходимо объявить функцию перед описанием ее тела. Для
этого используются прототипы функций (заголовки).
Прототип функций совпадает с заголовком определения, но в прототипе
можно опустить имена переменных в списке аргументов.
Следующие объявления равносильны:
int sum(int a, int b); ← ➔ int sum(int, int);
7. http://www.slideshare.net/IgorShkulipa 7
Пример использования прототипов функций
#include <iostream>
using namespace std;
int sum(int, int); // прототип функции
int mult(int, int); // прототип функции
int main ()
{
int a,b;
cin>>a>>b;
cout<<“a+b=”<<sum(a,b)<<“n”;
cout<<“a*b=”<<mult(a,b)<<“n”;
}
int sum (int a, int b)
{
return a+b;
}
int mult (int a, int b)
{
return a*b;
}
8. http://www.slideshare.net/IgorShkulipa 8
Параметры функции
Формальные параметры – данные, с которыми работает
функция. Это внутренние данные для функции. Они
перечисляются в заголовке функции и связаны с
фактическими параметрами.
Фактические параметры – данные, передаваемые в функцию
при ее вызове. Это внешние для функции данные, с которыми
имеет дело вызывающее окружение. В функции им
соответствуют формальные параметры.
Параметры = формальные параметры.
Аргументы = фактические параметры.
9. http://www.slideshare.net/IgorShkulipa 9
Передача аргументов функции
При передаче параметров
по значению они при
выходе из функции не
изменятся.
int func(int k)
{
k*=2;
return k;
}
void main()
{
int x=1;
int y=2;
int z;
z=func(x)+func(y);
cout<<x<<" "<<y<<" "<<z;
}
int func(int &k)
{
k*=2;
return k;
}
void main()
{
int x=1;
int y=2;
int z;
z=func(x)+func(y);
cout<<x<<" "<<y<<" "<<z;
}
При передаче параметров по
ссылке при выполнении
функции их значения могут
измениться.
10. http://www.slideshare.net/IgorShkulipa 10
Константные аргументы функции
Иногда возникает ситуация, когда нужно передать аргумент по ссылке и
при этом запретить его изменять.
Такая ситуация может возникнуть при работе с большими типами данных
(массивы, матрицы, вектора и т.д.), которые могут занимать сотни
байт. Если передавать эти аргументы в функцию по значению, то
будет происходить копирование, а это значит замедление программы.
Поэтому для большей эффективности можно передавать эти
переменные по ссылкам. А чтобы "случайно" не изменить их значения,
пользоваться константными аргументами.
int function(const int& a, int b);
{
a = 1; // Компилятор выдаст ошибку
return 0;
}
11. http://www.slideshare.net/IgorShkulipa 11
Функции с переменным числом параметров
Язык C++ позволяет описывать функции с переменным числом параметров. Одним из
простых примеров может служить функция, вычисляющая среднее арифметическое
своих аргументов.
Переменный список параметров задается в заголовке функции многоточием:
int function(…)
Имена параметров в явном виде отсутствуют, поэтому доступ можно осуществить только
одним способом – косвенным, используя указатель. Таким образом, список
параметров совсем пустой быть не может, должен быть указан хотя бы один явный
параметр, адрес которого мы можем получить при выполнении программы.
double average(double a1, ...)
{
double *p = &a1; // установка указателя на начало списка параметров
double sum = 0, count = 0;
while (*p) //пока указатель не равен нулю
{
sum+=(*p); //суммируем аргумент
p++; //перемещаемся на следующий аргумент
count++; //считаем количество аргументов
}
return ((sum)?(sum/count):0); //вычисляем среднее
}
12. http://www.slideshare.net/IgorShkulipa 12
Встраиваемые функции
Вызов функции, передача в неё значений, возврат значения, эти операции
занимают довольно много процессорного времени. Если размер функции
небольшой (несколько операторов), то время выполнения тела функции может
быть меньше чем процесс вызова/передачи аргументов/возврата значения.
Чтобы сократить время работы программы, можно воспользоваться встроенными
функциями.
В заголовок функции функции нужно добавить ключевое слово inline.
При этом, во время компиляции все вызовы функции будут заменены
непосредственно кодом функции. При этом программа будет выполняться
быстрее, но займёт больше памяти (если функция вызывается много раз):
Во время компиляции этот код превратится в следующий:
inline void print()
{
cout<<“Hello!”;
}
void main ()
{
print();
print();
print();
}
inline void print()
{
cout<<“Hello!”;
}
void main ()
{
cout<<“Hello!”;
cout<<“Hello!”;
cout<<“Hello!”;
}
13. http://www.slideshare.net/IgorShkulipa 13
Перегруженные функции
Часто возникает ситуация, когда несколько функций выполняют
одинаковые действия, только над разными типами. В данном случае
можно использовать перегруженные функции.
Перегруженные функции - это функции с одним именем, но с
разными типами аргументов:
int function (float a, float b);
int function (int a, int b);
int function (int a);
Здесь представлено три объявления перегруженной функции function.
Для каждого варианта функции, нужно описать своё определение.
Перегруженные функции могут отличаться не только типами аргументов,
но и их количеством.
В перегруженных функциях учитываются только аргументы, а не
возвращаемое значение
int wrong_function (int, int);
float wrong_function (int, int);!
14. http://www.slideshare.net/IgorShkulipa 14
Шаблоны функций
При создании функций иногда возникают ситуации, когда две функции
выполняют одинаковую работу, но работают с разными типами данных
(например, одна использует параметры типа int, а другая типа float).
С помощью механизма перегрузки функций можно использовать одно и
то же имя для функций, выполняющих разные действия и имеющих
разные типы параметров. Однако, если функции возвращают значения
разных типов, вам следует использовать для них уникальные имена.
Шаблон функции определяет типонезависимую функцию. С помощью
такого шаблона ваши программы в дальнейшем могут определить
конкретные функции с требуемыми типами.
template<class Тype>
Тype sum(Тype а, Тype b)
{
return (a+b);
}
Следующие прототипы создают функции типа float и int.
float sum(float, float);
int sum(int, int);
15. http://www.slideshare.net/IgorShkulipa 15
Шаблоны, которые используют несколько типов
Предыдущее определение шаблона для функции sum использовало
единственный общий тип Тype. Очень часто в шаблоне функции
требуется указать несколько типов.
template<class Type1, class Type2, class Type3>
Type1 function(Type2 var1, Type3 var2)
{
cout << var1<<“n”;
cout << var2<<“n”;
}
Как и ранее, необходимо указать прототипы функций для требуемых
типов:
void function (int, int);
int function (float, unsigned);
16. http://www.slideshare.net/IgorShkulipa 16
Указатели на функции
Указатели на функции задаются следующим образом:
<тип> (*<имя переменной>)();
void function()
{
cout<<“Hello, World with Function Pointers!”;
}
void main()
{
void (*pf)() = &function;
pf();
}
В этом коде:
function - некоторая функция.
pf – это переменная, которая является указателем на
функцию, которая ничего не возвращает и не принимает ни
одного аргумента. В определении pf ей присваивается
адрес функции function. В третьей строке мы вызываем
функцию по указателю pf(в данном случае будет вызвана
функция function)
17. http://www.slideshare.net/IgorShkulipa 17
Рекурсия
В С++ функции могут вызывать сами себя. Функция является
рекурсивной, если оператор в теле функции вызывает функцию,
содержащую данный оператор.
Рекурсия
НеявнаяЯвная
double y_n(unsigned double n)
{
if (n==1) return 1;
else
return sqrt(n + y_n(n-1));
}
double function1();
double function2()
{
function1();
}
double function1()
{
function2();
}
18. http://www.slideshare.net/IgorShkulipa 18
Лабораторная работа №3. Функции.
Задание:
1. Создать рекурсивную функцию, вычисляющую факториал
числа N, введенного с клавиатуры. Результат работы
программы вывести на экран.
2. Создать рекурсивную функцию, возвращающую количество
цифр в строке. С помощью данной функции определить, в
каком из двух введенных с клавиатуры предложений цифр
больше.