Похожие презентации:
Тема 7 Функции
1. Тема 7. Функции
Факультет электротехники и автоматики2. Понятие функции
Нетривиальные программы на С/C++ состоят из функций,одна из которых должна иметь имя main. Функция является
логически самостоятельной именованной частью программы
и выполняет какое-то законченное действие. Функции могут
передаваться параметры и она может возвращать некоторое
значение.
Программа на С/C++
Точка входа
(main)
Другие
Другиефайлы
файлы
Функции
(.h)
(.h)
Разделение программы на функции позволяет избежать
избыточности кода, объединить часто используемые
функции в библиотеки и создать модульные, более простые
в сопровождении, программы.
2
3. Объявление функции
Для объявления функции следует задать тип возвращаемогозначения (если оно есть), имя функции и список параметров.
Имена параметров указывать не обязательно. В конце
объявления ставится точка с запятой.
double square(double length, double width);
Список параметров
Тип
возвращаемого
Имя функции
значения
Тип функции
Тип параметра
Имя параметра
Объявление
(прототип,
заголовок)
функции
можно
воспринимать как ее интерфейс. Как правило, объявления
располагаются в файлах с расширением .h или .hpp.
3
4. Определение функции
Каждая функция, вызываемая в программе, должна бытьопределена (и только один раз) в одном из файлов проекта.
Определение функции описывает, что должна делать
функция. Оно состоит из объявления и тела функции,
которое представляет собой заключенную в фигурные
скобки совокупность инструкций.
double square(double l, double w)
{
return l * w;
//тело функции
}
Типы в определении и объявлениях функции должны
совпадать. Однако, имена параметров не обязаны
совпадать.
4
5. Вызов функции
Для вызова функции надо указать ее имя. Затем в круглыхскобках через запятую перечисляются имена переменных,
которые являются ее аргументами. Тип и порядок
следования аргументов должен совпадать с объявлением и
определением.
int main ()
{
double a, b;
...
double s = square(a, b);
}
Вызов функции может находиться в любом месте
программы, где по синтаксису допустимо выражение того
типа, который формирует функция.
5
6. Применение функций (пример 1)
Текст модуля lib.cpp#include <iostream>
using namespace std;
int abs(int val);
int main()
{
int a;
cin >> a;
cout << abs(a);
}
//объявление функции
//место вызова функции
int abs(int val)
//определение функции
{
return(val<0) ? –val : val;
}
6
7. Применение функций (пример 2)
Текст модуля lib.cpp#include <iostream>
using namespace std;
int abs(int val)
//определение функции
{
return(val<0) ? –val : val;
}
int main()
{
int a;
cin >> a;
cout << abs(a);
}
//место вызова функции
7
8. Модульное программирование
Текст заголовка lib.hОбъявление (прототип функции)
int abs(int val);
Текст модуля prog.cpp
Текст модуля lib.cpp
int abs(int val)
{
if(val < 0)
val = -val;
return val;
}
//подключить объявление
#include "lib.h"
...
Вызов
int a = abs(b);
...
int c = a+abs(d);
Вызов
Определение (тело функции)
8
9. Классы памяти для функций
Для функций могут быть заданы классы памяти extern (поумолчанию) или static. Если класс не задан (или задан
extern), то функция может вызываться любым модулем
программы. Если задан класс static, то функция может
вызываться только в том модуле, в котором она определена.
Текст заголовка lib.h
static int abs(int val);
Текст модуля prog.cpp
#include "lib.h"
...
Текст модуля lib.cpp
int a = abs(b);//ошибка
int abs(int val)
//функцию abs можно
{
//использовать только
return(val<0) ? –val : val; //в модуле lib.cpp
}
9
10. Возвращаемое функцией значение
10Возвращаемое функцией значение
Функции возвращают результат своих действий, если они не
объявлены с типом void. Инструкция return реализует
механизм возврата результата от вызываемой к вызывающей
функции. За ключевым словом return должно следовать
выражение, соответствующее типу возвращаемого значения,
если он отличен от void.
Функция с типом int
int min(int a, int b)
{
if(a <= b)
return a;
else
return b;
}
Функция с типом void
void min(int a, int b)
{
if(a <= b)
cout << a;
else
cout << b;
return;//можно опустить
}
11. Параметры (аргументы) функции
11Параметры предназначены для передачи некоторых
значений из вызывающей функции в вызываемую.
Параметры всегда являются локальными переменными,
областью видимости которых является тело функции.
Существуют разные способы передачи параметров в
функцию: по значению, по ссылке и через указатель.
Пример функции
int min(int a, int b)
{
if(a <= b)
return(a);
else
return(b);
}
Пример функции
void swap(int &a, int &b)
{
int c = a;
a = b;
b = c;
}
12. Вызов функции с передачей значения
12При данном способе вызова передаваемые в функцию
переменные копируются в локальные переменные
функции. Вызываемая функция не может воздействовать
на переменные, передаваемые в качестве параметров.
Пример кода
void add(int x)
{
x += 1;
}
...
int a = 5;
add(a);
a = 5
13. Вызов функции с передачей по ссылке
13При данном способе вызова в функцию передаются не копии
переменных, а их адреса в неявном виде (по ссылке).
Вызываемая
функция
может
изменять
значения
передаваемых ей переменных. Для передачи по ссылке
используется оператор & при описании типов передаваемых
параметров.
Пример кода
void add(int &x)
{
x += 1;
}
...
int a = 5;
a = 6
add(a);
Так как структуры (особенно большие) не эффективно
передавать по значению, их всегда надо передавать по ссылке.
14. Вызов функции с передачей через указатель
14При данном способе вызова в функцию передаются не копии
переменных, а их адреса в явном виде. Вызываемая
функция может изменять значения передаваемых ей
переменных с помощью разыменования указателя. Для
передачи адреса используется оператор & перед именем
переменной (для массива можно использовать имя без &).
Пример кода
void add(int* x)
{
*x += 1;
}
...
int a = 5;
add(&a);
a = 6
Массивы всегда передаются через указатель.
15. Значения параметров по умолчанию
15При объявлении функции можно указать значение
параметров по умолчанию. Они должны быть последними в
списке параметров и могут опускаться при вызове функции.
Объявление функции
int func(int a, int b = 3, int c = 5);
Значение параметров по умолчанию
Пример кода
int func(int a, int b, int c) {return(a+b+c);}
...
x = 14
int x = func(7, 5, 2);
int x = func(7, 5);
x = 17
int x = func(7);
x = 15
int x = func(); Ошибка!
16. Статические локальные переменные внутри функций
16Статическая локальная переменная объявляется с ключевым
словом static. Она инициализируется один раз (при первом
выполнении строки, содержащей ее объявление) и сохраняет
свое значение между вызовами функции.
Пример кода
int count () {
static int c = 0; //статическая
return c++;
//переменная
}
int main() {
cout << count() << endl; // 0
cout << count() << endl; // 1
cout << count() << endl; // 2
}
17. Неуказанное кол-во параметров
17Если невозможно указать количество и типы всех
аргументов, то их список можно закончить многоточием. Для
доступа к необязательным параметрам внутри функции
используются va_ макросы.
Лучше не применять!
Пример кода
int sprintf(char* buf, const char *format, ...)
{
При инициализации
va_list args;
va_start(args, format); указывают последний
фиксированный параметр
while(int* par = va_arg(args, int*))
{
Получение следующего
...
параметра типа int*
}
va_end(args);
Необходимо вызвать в конце
}
18. Рекурсивный вызов функции
18Рекурсивной называется функция, которая вызывает саму
себя. Для завершения вычислений рекурсивная функция
должна содержать хотя бы одну нерекурсивную ветвь
алгоритма, заканчивающуюся инструкцией return.
Пример рекурсии
Пример без рекурсии
long fact(long N)
{
if(N <= 1) return 1;
return(N*fact(N-1));
}
...
cout << fact(9);
long fact(long N)
{
long f = 1;
for(long i=2;i<=N;i++)
f *= i;
return f;
}
cout << fact(9);
Любую рекурсивную функцию можно реализовать без рекурсии
19. inline функции
19Для каждого вызова функции происходят некоторые
накладные затраты, связанные с запоминанием точки
возврата, значений регистров процессора и передачей
аргументов. Для небольших функций такие затраты
существенны относительно их времени выполнения. В этом
случае имеет смысл использовать встроенные функции с
помощью директивы inline.
Пример inline функции
inline int abs(int val)
{
return (val <0 ) ? –val : val;
}
Компилятор будет пытаться каждый раз вместо вызова
функции встроить ее код. Это приведет к увеличению
размера программы, но может повысить ее быстродействие.
Программирование