Функции в языке С++
Функции. Определение
Функции. Синтаксис С++
Особенности функций Возвращаемое значение типа void
Особенности функций Функции inline
Особенности функций Вычисление аргументов функции
Особенности функций Передача параметров в функцию
Особенности функций Передача параметров в функцию
Особенности функций Передача параметров в функцию
Рекурсия
Задачи
72.56K
Категория: ПрограммированиеПрограммирование

Функции в языке С++

1. Функции в языке С++

2. Функции. Определение

Функция - фрагмент кода, к которому можно обращаться из
другого места программы.
Функции в С/С++ определяются именем функции, принимаемыми
аргументами и возвращаемым значением.
Прямая аналогия - функции в математике.
y = f(x)
f: X -> Y
где: f - имя функции,
x - аргумент,
y - возвращаемое значение

3. Функции. Синтаксис С++

<возвращаемое значение> <имя функции> (<аргументы через запятую>) {
<тело функции>
return <значение функции>;
}
На примере функции возведения в степень:
double mpow(const double x, int n) {
int result = x;
while (--n != 0) {
result*=x;
}
return result;
}
//в коде можно уже будет просто обратиться к функции
double y = mpow(2, 5); //y = 32
Благодаря механизму неявного приведения типов в С++, аргументами такой функции могут стать и переменные
других типов. Возвращаемое значение так же может записаться в переменную другого типа, если компилятор
сможет выполнить преобразование.
Но за всем этим лучше следить самому, иногда неявные преобразования могут привести к непредсказуемым
результатам:
char y = mpow(2,9); //выполнится без ошибок, но результат будет достаточно странным

4. Особенности функций Возвращаемое значение типа void

Функция с таким возвращаемым значением реально ничего не
вернет (вернется "пустышка" void).
В таких функция можно не писать return.
void printArray(int* arr, const int sizeArr) {
for (int i = 0; i < sizeArr; ++i) {
std::cout << arr[i] << " ";
}
std::cout << endl;
//return;
}

5. Особенности функций Функции inline

Ключевое слово inline перед определением функции указывает компилятору, что
код функции надо напрямую вставлять в место вызова.
Может не сработать, если компилятор посчитает, что это не нужно ¯\_(ツ)_/¯.
Редко встречаются, разве что в специфических задачах, требующих огромной
скорости работы.
inline double mAbs(const double value) {
return value >= 0 ? value : -value;
}
...
int a = mAbs(-6);
Компилятор будет в итоге работать с таким кодом:
int a = return -6 >= 0 ? value : -value;

6. Особенности функций Вычисление аргументов функции

Аргументы могут вычисляться компилятором в произвольном
порядке, но гарантируется, что к началу работы функции они будут
вычислены.
printf("%d %d %d \n", i, ++i + ++i, i);
Такая ситуация называется неопреленным поведением (Undefined
Behavior).

7. Особенности функций Передача параметров в функцию

Передача по значению (pass-by-value):
В функцию передается значение аргумента, следовательно, ЛОКАЛЬНЫМ
переменным-аргументам просто присваиваются переданные значения.
Сами передаваемые в момент вызова функции переменные НЕ ИЗМЕНЯТСЯ.
void sum2(double a, const double b) {
//a = 5.5, b = 4.2
a+=b;
//a = 9.7
}
...
double a = 5.5, b = 4.2;
sum2(a, b);
//a = 5.5, b = 4.2

8. Особенности функций Передача параметров в функцию

Передача по ссылке (pass-by-reference):
В функцию передается ссылка на объект, следовательно, значение передаваемого
объекта может измениться в теле функции.
Чаще применяется при работе "обычными" переменными.
void sum2(double &a, const double &b) {
//a = 5.5, b = 4.2
a+=b;
//a = 9.7
b = 0;
}
...
double a = 5.5, b = 4.2;
sum2(a, b);
//a = 9.7, b = 0

9. Особенности функций Передача параметров в функцию

Передача по указателю (pass-by-pointer):
В функцию передается указатель на объект, значение передаваемого объекта может измениться
в теле функции.
Массивы, структуры и объекты классов следует передавать через указатель.
double sumArray(double *arr, int n) {
sum = 0;
for (int i = 0; i < n; ++i) {
sum+=arr[i];
}
return sum;
}
...
double staticArray[5] = {0, 1, 2, 3, 4};
double firstSum = sumArray(staticArray, 5); //array - указатель на первый элемент
массива
double *dynamicArray = new int[5];
... //заполнение массива
double secondSum = sumArray(dynamicArray, 5);

10. Рекурсия

Внезапно, но в коде функции можно вызывать эту же функцию. Это позволяет более элегантно решать некоторые
задачи,
но стоит самостоятельно следить за тем, когда стоит остановить рекурсию. Если не поставить условий на выход из
рекурсии,
то неконтролируемый вызов кучи функций заполнит всю память на стеке и программа упадет.
Пример рекурсивной функции (бинарный поиск):
int binarySearch(int *arr, int elem, int left, int right) {
int med = (left + right) / 2;
if (arr[med] == elem) {
return med;
}
if (med == left || med == right) {
return -1;
}
if (arr[med] > elem) {
binarySearch(arr, elem, 0, med);
}
else {
binarySearch(arr, elem, med + 1, right);
}
}

11. Задачи

Задача 1
Реализовать функцию сортировки массива методом
пузырька
Задача 2
Реализовать функцию приведения строки к верхнему
регистру
Задача 3 (*)
Реализовать функцию сортировки массива методом
быстрой сортировки (quicksort)
English     Русский Правила