c++ Базовый. Занятие 03

18
Модуль 1 : Базовые понятия языка программирования С++ Темы лекции : Функции языка С++. Практическое задание : Функции языка С++. Тренер: Игорь Шкулипа, к.т.н. C++ Базовый. Занятие 3

Upload: igor-shkulipa

Post on 21-Mar-2017

42 views

Category:

Education


0 download

TRANSCRIPT

Модуль 1: Базовые понятия языка программирования С++

Темы лекции: Функции языка С++.

Практическое задание: Функции языка С++.

Тренер: Игорь Шкулипа, к.т.н.

C++ Базовый. Занятие 3

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));

}

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;

}

Идентификатор (имя)функции задаётся точнотакже, как и любой другойидентификатор.

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;

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 является

отладчик или операционная система.

http://www.slideshare.net/IgorShkulipa 6

Прототипы функций

Для того, чтобы функция могла быть вызвана, она должна бытьобъявлена перед тем местом, где она вызывается. Бывают случаи,когда необходимо объявить функцию перед описанием ее тела. Дляэтого используются прототипы функций (заголовки).

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

Следующие объявления равносильны:

int sum(int a, int b); ← ➔ int sum(int, int);

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;

}

http://www.slideshare.net/IgorShkulipa 8

Параметры функции

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

Фактические параметры – данные, передаваемые в функциюпри ее вызове. Это внешние для функции данные, с которымиимеет дело вызывающее окружение. В функции имсоответствуют формальные параметры.

Параметры = формальные параметры.

Аргументы = фактические параметры.

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;

}

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

http://www.slideshare.net/IgorShkulipa 10

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

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

Такая ситуация может возникнуть при работе с большими типами данных(массивы, матрицы, вектора и т.д.), которые могут занимать сотнибайт. Если передавать эти аргументы в функцию по значению, тобудет происходить копирование, а это значит замедление программы.Поэтому для большей эффективности можно передавать этипеременные по ссылкам. А чтобы "случайно" не изменить их значения,пользоваться константными аргументами.

int function(const int& a, int b);

{

a = 1; // Компилятор выдаст ошибку

return 0;

}

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); //вычисляем среднее

}

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!”;

}

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);!

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);

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);

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)

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();

}

http://www.slideshare.net/IgorShkulipa 18

Лабораторная работа №3. Функции.

Задание:

1. Создать рекурсивную функцию, вычисляющую факториалчисла N, введенного с клавиатуры. Результат работыпрограммы вывести на экран.

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