Функции в C++
При написании программы часто требуется выполнить одинаковую последовательность операций для получения какого-либо результата. К примеру, предположим, что необходимо получить процентное отношения для двух исходных чисел:
#include <iostream> using namespace std; int main(int argc, char *argv[]) { int a = 1; int b = 10; double result1 = 100.0 * a / b; cout << result1 << '\n'; int c = 2; int d = 30; double result2 = 100.0 * c / d; cout << result2 << '\n'; }
В обоих случая повторяется одна и та же последовательность, что в этом случае, вообщем-то не мешает, но может сильно навредить, если такие части будут повторяться в различных участках проекта. Удобней вынести этот общий блок операций, дать ему какое-то имя и вызывать по мере необходимости. Функция в программе, так же как и функция в её математическом смысле, имеет аргументы и возвращаемое значение. Совокупность имени функции, её аргументов и возвращаемого значения называется сигнатурой метода (или функции).
В C++ как и во многих других языках программирования функции нельзя описать внутри другой функции, а требуется описать её отдельно. Таким образом, пример, описанный выше можно описать так:
#include <iostream> using namespace std; double percentage(int a, int b) { return 100.0 * a / b; } int main(int argc, char *argv[]) { double result1 = percentage(1, 10); cout << result1 << '\n'; double result2 = percentage(2, 30); cout << result2 << '\n'; }
Несколько функций можно группировать в области видимости. Возможность объединить несколько функций в рамках некоторого именованного пространства позволяет избежать коллизий имён с аналогичными функциями из других подключаемых библиотек, да и просто логически организовать ваш код. Слегка изменим код выше, введя в него две новых функций и разделяя его в разные логические структуры:
#include <iostream> using namespace std; namespace Math { double percentage(int a, int b) { return 100.0 * a / b; } double sum(int a, int b) { return a + b; } } namespace IO { void printLine(double result) { cout << result << '\n'; } } int main(int argc, char *argv[]) { double result1 = Math::percentage(1, 10); IO::printLine(result1); double result2 = Math::percentage(2, 30); IO::printLine(result2); }
Кстати, ключевое слова using namespace std;
позволяет для метода (функции) cout
писать без указания именованного пространства, к которому оно относится.
Функции и её аргументы
Передача аргументов в функции может быть по значению или по ссылке. В первом случае, значение которое используется в функции является копией значения, которое передаётся в функцию. Во втором передаётся само значения без его копирования.
#include <iostream> using namespace std; void byValue(int a) { a = 2; } void byReference(int& a) { a = 2; } int main(int argc, char *argv[]) { int value = 6; byValue(value); cout << "By value:\t\t" << value << '\n'; byReference(value); cout << "By reference:\t" << value << '\n'; }
Ввывод в консоли:
By value: 6 By reference: 2
После вызова метода, который передаёт аргумент по ссылке, значение переменной value
изменяется. Таким образом, с одной стороны имеется возможность не копировать значение (а процесс копирования может быть весьма затратен), но с другой стороны не гарантируется никаким образом неизменяемость значения переменной. Для того, чтобы гарантировать в коде, что переданное значение не будет изменено внутри метода к аргументу добавляют модификатор const
:
void byReference(const int& a) { a = 2; }
При компиляции проекта будет выведена следующая ошибка:
Untitled.cpp:10:4: error: read-only variable is not assignable a = 2; ~ ^ 1 error generated.