Функции и указатели в C++



Функции

В языке С++ присутствует возможность использовать функции, то есть логичекские структурные единицы кода, которые позволяют сделать код более читаемым и разделить функционал.

myFunction.cpp

Синтаксис функций можно описать следующим образом:

тип_возвращаемого_значения название_функции(аргументы_функции)
{
    ... код функции ...
}

Пример функции, возвращающей наибольшее число из двух:

int max(int x, int y)
{
    if (x > y)
        return x;
    else
        return y;
}

Вызов функции выглядит следующим образом:

int a = 150;
int b = 980;

int c = max(a, b) // Функция вернет значение 980

Указатели

Попробуем реализовать функцию, которая принимает 3 integer переменных, сравнивает 2 из них и результат сравнения(наибольшее из чисел) записывает в третий аргумент.

madMax.cpp

Кажется логичным сделать подобную реализацию этой функции:

void max(int x, int y, int c)
{
    if (x > y)
        c = x;
    else
        c = y;
}

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

int a = 150;
int b = 980;

int c = 0;
max(a, b, c)

std::cout << c; // Печатает 0 а не 980.

Что произошло? Все дело в том, что при вызове функции в ее аргументы были переданы всего лишь значения переменных a, b, c, которые равнялись соответственно 150, 980 и 0. Поэтому внутри функции были созданы переменные x, y, c в которых хранились эти значения, но эти переменные лежат совсем по другим адресам в оперативной памяти. Соответственно, изменение значений переменных внутри функций приводит к тому, что они изменяются не по тем адресам, в которых лежат переменные вызывающей стороны.

Указатели - это один из способов, позволяющих решить данную проблему. Идея заключается в том, чтобы передавать не значение переменной, а ее адрес в оперативной памяти, по которму можно определить и изменить значение.

Тогда с учетом этого, функция max() должна быть модифицирована следующим образом:

void max(int x, int y, int* c)
{
    if (x > y)
        *c = x;
    else
        *c = y;
}

Где int* - это тип аргумента, означающий адрес на переменную типа integer. Оператр * позволяет обратиться по адресу данной переменной и считать или записать значение.

Как же теперь вызывать эту функцию?

int a = 150;
int b = 980;

int c = 0;
max(a, b, &c)

std::cout << c; // Печатает 980

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