Добавлен , опубликован

Основы программирования Корсаров

Содержание:

Передача переменной в функцию

void NumChanger (int a)
{
    a = 12;
}

void myFunc ()
{
    int num = 10;

    NumChanger(num);
    trace("num = " + num);  // Результат: "num = 10"
}
В примере выше, мы передаем в функцию NumChanger() число 10 из в переменной num, которое попадает в переменную a. А затем изменяем значение переменной a на 12.
Но переменная a - это локальная переменная, созданная для функции NumChanger() и её изменение никак не отразится на переменной num. В ней по-прежнему будет находиться число 10.
Это происходит потому, что С++ копирует данные, которые мы передаём в функцию, в локальные переменные-аргументы.
Это очень удобно - мы можем спокойно работать с данными в одной функции, не беспокоясь об остальных функциях, которые используют эти же данные.
Но бывают ситуации, когда нам нужно, как раз таки, изменить данные, которые мы передаём. Конечно же, мы могли бы передать данные в нашу функцию, обработать их, вернуть новое значение и присвоить его исходной переменной. Но это, во-первых, лишний код, во-вторых лишние операции - создание ненужных переменных и перебрасывание информации туда-сюда.
Для таких задач существует передача данных по ссылке:
void NumChanger (ref a)
{
    a = 12;
}

void myFunc ()
{
    int num = 10;

    NumChanger(&num);
    trace("num = " + num);  // Результат: "num = 12"
}
Тот же пример, только с некоторыми изменениями. Во-первых, функция NumChanger() теперь принимает тип данных ref (ссылка). Во-вторых, изменился и сам вызов этой функции: NumChanger(&num);. Перед именем переменной появился амперсанд (символ &). Он указывает компьютеру, что нужно передать адрес переменной в памяти, а не её значение.
Таким образом, изменяя значение переменной a внутри функции NumChanger(), мы изменяем значение переменной num. Потому что a теперь вовсе не переменная, а ссылка на переменную num.

Возврат данных

Точно такие же правила действуют и на передачу данных при возврате посредством оператора return:
int myGlobalVar = 10;

ref GetNum ()
{
    return &myGlobalVar;
}

void myFunc ()
{
    ref num = GetNum;
    
    trace("num = " + num);  // Результат: "num = 10"
}
Функция вполне может возвращать ссылку на какой-то объект. Но для этого нужно указать соответствующий тип возврата, а также тип переменной, в которую мы этот возврат помещаем.

Передача массива

Передача массива в функцию на первый взгляд выглядит так же, как передача обычной переменной. Однако, массив может быть очень большим и его копирование — дело очень ресурсозатратное. Поэтому C++ не копирует массив при его передаче в функцию, а передаёт фактический массив. И здесь мы получаем побочный эффект, позволяющий функциям напрямую изменять значения элементов массива.
ОСОБЕННОСТЬ скриптовой части Корсаров, в данном случае, работает скорее как плюс для понимания кода. Мы должны явно указывать, что передаём ссылку, а не саму переменную массива:
void changeArray (ref arr)
{
    arr[0] = 3;
    arr[1] = 5;
    arr[2] = 7;
}

void myFunc()
{
    
    int anotherArray[3];

    anotherArray[0] = 2;
    anotherArray[1] = 4;
    anotherArray[2] = 6;

    // выводим объявленный массив
    trace("До изменения: " + anotherArray[0] + ", " + anotherArray[1] + ", " + anotherArray[2]);    // Результат "До изменения: 2, 4, 6"

    // изменяем массив
    changeArray(&anotherArray);
    // выводим ещё раз
    trace("После изменения: " + anotherArray[0] + ", " + anotherArray[1] + ", " + anotherArray[2]); // А здесь "После изменения: 3, 5, 7"
}

`
ОЖИДАНИЕ РЕКЛАМЫ...
0
29
0
out завезли?
Ответы (4)
0
22
0
nazarpunk, или я что-то не понял, или твой out это просто переданная ссылка, в которую ты данные закидываеш, а не используеш.
Если да - то да, передача ссылок присутствует и такие финты делать можно.
0
29
0
avuremybe, ну как-бы это ссылка, но с типом. Как по нотации функции понять какой тип ожидается в a?
void NumChanger (ref a)
{
}
0
22
0
nazarpunk, никак не понять. Тут ссылочный тип проприетарный, еще и на костылях.
С этим сложности, да. Поэтому макимально всем рекомендуется подписывать типы данных в названии переменных, чтоб хоть как-то снизить жопную боль.
0
5
0
Поэтому максимально всем рекомендуется подписывать типы данных в названии переменных, чтоб хоть как-то снизить жопную боль.
Как правило, этого достаточно, но в движке есть varType на такой случай, в скриптах пока никем нигде не применялось)
Чтобы оставить комментарий, пожалуйста, войдите на сайт.