Передача переменной в функцию
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.
Это происходит потому, что С++ копирует данные, которые мы передаём в функцию, в локальные переменные-аргументы.
Но переменная 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.
Таким образом, изменяя значение переменной 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"
}
Ред. avuremybe
Если да - то да, передача ссылок присутствует и такие финты делать можно.
Ред. nazarpunk
С этим сложности, да. Поэтому макимально всем рекомендуется подписывать типы данных в названии переменных, чтоб хоть как-то снизить жопную боль.
Ред. Rosarak