Этот вопрос на самом деле сильно зависит от конкретного языка, поскольку некоторые позволяют вам быть явными и определять, когда вы хотите передать переменную по значению, а когда по ссылке, а некоторые делают это всегда одинаково для разных типов переменных.
Довольно популярным типом поведения является использование передачи по значению (по умолчанию) для простых времен: таких как int, string, long, float, double, bool et c.
Давайте покажем влияние памяти на теоретический язык:
int $myVariable = 5;
в этот момент вы создали одну переменную в памяти, которая принимает размер, необходимый для хранения целого числа (скажем, 32 бита).
Теперь вы хотите передать его в функцию:
function someFunction(int parameter)
{
printOnScreen(parameter);
}
, чтобы ваш код выглядел следующим образом:
function someFunction(int $parameter)
{
printOnScreen($parameter);
}
int $myVariable = 5; //Position A
someFunction($myVariable); //Position B
...rest of the code //Position C
Поскольку простые типы передаются по значению, значение копируется в память в другое место хранения - следовательно:
во время положения A у вас есть память, занятая ONE int (со значением 5); во время положения B у вас есть память, занятая ДВУМИ целыми числами (со значениями 5), так как ваша переменная $ myVariable была скопирована в память во время положения C, у вас снова есть память, занятая ONE int (со значением 5), поскольку второй был уже уничтожен поскольку это было необходимо только на время выполнения функции
Это имеет некоторые другие последствия: изменения в переменной, передаваемой по значению, НЕ влияют на исходную переменную - например:
function someFunction(int $parameter)
{
$parameter = $parameter + 1;
printOnScreen($parameter);
}
int $myVariable = 5; //Position A
someFunction($myVariable); //Position B
printOnScreen($myVariable); //Position C
Во время положения A вы устанавливаете значение 5 в переменной $ myVariable. Во время положения B вы передаете его BY VALUE функции, которая добавляет 1 к вашему переданному значению. ДА, так как это был простой тип, передаваемый по значению, он фактически работает с локальной переменной, копией вашей переменной. Поэтому позиция C снова напишет только 5 (ваша исходная переменная, поскольку она не была изменена).
Некоторые языки позволяют вам быть явными и сообщать, что вы хотите передать ссылку, а не само значение, используя специальный оператор - например &
. Итак, давайте снова последуем тому же примеру, но с явной информацией, на которую мы хотим ссылаться (в аргументах функции - обратите внимание на &
):
function someFunction(int &$parameter)
{
$parameter = $parameter + 1;
printOnScreen($parameter);
}
int $myVariable = 5; //Position A
someFunction($myVariable); //Position B
printOnScreen($myVariable); //Position C
Это время операции и последствия для памяти будут другими.
Во время позиции A создается int (каждая переменная всегда состоит из двух элементов: места в памяти и указателя, идентификатора, в каком месте он находится. Для простоты процесса допустим, что указатель всегда равен одному байту) , Поэтому, когда вы создаете переменную, вы на самом деле создаете две вещи:
- зарезервированное место в памяти для значения VALUE (в данном случае 32 бита, как это было целым числом)
- указатель (8 битов) [1 байт])
Теперь в положении B функция ожидает указатель A на место в памяти. Это означает, что он будет локально создавать для себя только копию указателя (1 байт) и не будет копировать фактическое зарезервированное место в качестве нового указателя WILLL POINT в то же место, что и исходный. Это означает, что во время работы функции у вас есть:
ДВА указателя на int в памяти. ОДНО место, зарезервированное для VALUE для int. Оба этих указателя POINT указывают на одно и то же VALUE
Что означает, что любая модификация значения будет влиять на оба.
Поэтому, глядя на ту же позицию примера C не будет выводить также 6, поскольку внутри функции, которую мы изменили значение в ОДНОМ ЖЕ УКАЗАТЕЛЕ, как $ myVariable.
Для СЛОЖНЫХ ТИПОВ (объектов) действием по умолчанию в большинстве сред программирования является передача ссылки (указателя).
Например, если у вас есть класс:
class Person {
public string $name;
}
и создайте его экземпляр и установите значение:
$john = new Person();
$john->name = "John Malkovic";
, а затем передайте его функции:
function printName(Person $instanceOfPerson)
{
printOnScreen($instanceOfPerson);
}
с точки зрения памяти, он снова создаст только новый указатель в памяти (1 байт), которая указывает на то же значение. Таким образом, имея такой код:
function printName(Person $instanceOfPerson)
{
printOnScreen($instanceOfPerson);
}
$john = new Person(); // position A
printName($john); // position B
...rest of the code // position C
во время положения A, вы получаете: 1 человека (что означает 1 указатель [1 байт] на место в памяти, размер которого позволяет хранить объект класса person)
во время позиции B у вас есть: 2 указателя [2 байта], но ЕЩЕ ОДНО место в памяти для хранения объекта значения класса [экземпляр]
во время позиции C у вас снова ситуация из позиции A
Я надеюсь, что это проясняет для вас топи c - как правило, есть еще кое-что, и то, что я упомянул выше, является лишь общим объяснением.