Функции в 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.

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: