Передача по значению против передачи по ссылке (разница в распределении памяти между двумя)

В C++, где мы используем передачу по ссылке, мы ссылаемся на адрес того, что мы передали из аргумента в параметр функции, который по сути является указателем, верно? Итак, хотя они, по сути, одно и то же, псевдоним и все, не требует ли указатель места в памяти? Поэтому, если все, что у нас есть в функции параметра, позвольте нам вызывать B, указывает на область памяти любого передаваемого аргумента, давайте вызывать A, который, в свою очередь, является ячейкой памяти нашего значения (так как A передал ячейку памяти нашего значения в качестве аргумента)?

В java, где мы используем передачу по значению, мы делаем копию адреса того, что было передано нам (например, ссылка на объект).

Так что, в конце концов, я не вижу разницы между передачей по значению и передачей по ссылке. Передача по значению выделяет пространство в памяти для исходного переданного аргумента, а копия, которая и указывает на значение, и передает по ссылке, передает местоположение в памяти нашего значения в качестве аргумента, который параметр (указатель, который выделяет пространство в памяти) в нашем Функция использует для указания значения.

3 ответа

Решение

В C++, где мы используем передачу по ссылке, мы ссылаемся на адрес того, что мы передали из аргумента в параметр функции, который по сути является указателем, верно?

Нет. Ссылка - это псевдоним (то есть альтернативное имя) для существующей переменной.
Но на уровне сборки ваша реализация может поместить адрес ссылочной переменной в регистр адресов (или что-то подобное) для использования вызываемой функцией (если это то, что вы имеете в виду).

Но для упрощения вы можете думать об этом как о указателе, который автоматически разыменовывается (это то, что я делал, когда впервые запускал). Но когда вы попадаете на язык, ссылки на самом деле принципиально отличаются от указателей.

Итак, хотя они, по сути, одно и то же, псевдоним и все, не требует ли указатель места в памяти?

Указатель на уровне C++ требует места (так как он адресуемый). Вы можете взять адрес указателя. Принципиально ссылка не требует места (так как вы не можете взять ее адрес). На уровне реализации он может иметь или не иметь физическую ячейку памяти в зависимости от того, как ее реализует компилятор.

Поэтому, если все, что у нас есть в параметрической функции, позвольте нам вызывать B, указывает на место в памяти любого передаваемого аргумента, давайте вызывать A

Было бы неплохо, если бы вы объяснили выше пример кода. Но я думаю, что понимаю. Если предположить, что функция не встроена, то любой параметр, переданный в качестве ссылки, нуждается в некоторой форме обратной ссылки на исходный объект (поскольку ссылки всегда фундаментально ссылаются на живые объекты). Так как это сделать. Детали реализации компилятора (так что вам не важно). Но, возможно, указатель на стек или, может быть, просто адрес в регистре адресов.

которая, в свою очередь, является ячейкой памяти нашего значения (поскольку A передала ячейку памяти нашего значения в качестве аргумента)?

Может быть или нет. Ссылки не имеют физического местоположения на уровне языка. Таким образом, компилятор может сыграть много хороших маленьких трюков с этим.

В java, где мы используем передачу по значению, мы делаем копию адреса того, что было передано нам (например, ссылка на объект).

В Java вы передаете ссылки по значению. Но ссылки на Java - это просто указатели в ячейке памяти. Итак, вы передаете указатель по значению. Какой метод использовать? К счастью, C++ не ограничивает вас одной техникой.

Вы можете передавать параметры по значению или по ссылке. Вы даже можете передать указатель на объект по значению или по ссылке. Итак, пара интересных техник для использования в зависимости от ситуации.

Так что, в конце концов, я не вижу разницы между передачей по значению и передачей по ссылке.

Может быть, это потому, что вы думаете о ссылках Java (которые передаются по значению).

В С ++. Если вы передаете по значению, вы создаете новый объект, который передается в качестве параметра (что означает, что вы делаете копию оригинала, что может стоить). Если вы передаете по ссылке, вы передаете псевдоним объекту. Поэтому, когда вы взаимодействуете с объектом, вы модифицируете исходный объект.

 int inc(int val)     // pass by value
 {
     return ++val;    // increment the passed value and return as a result.
 }

 int incref(int& val) // pass by reference
 {
     return ++val;    // increment the reference.
                      // Since the reference is an alias this increment affects the
                      // original object. The result is returned.
 }

 void code()
 {
       int x = 5;
       int y = inc(x);  // x =5 and y = 6

       int a = 8;
       int b = incref(a); // a = 9 and b = 9
 }  

Передача по значению выделяет пространство в памяти для исходного переданного аргумента, а копия, которая и указывает на значение, и передает по ссылке, передает местоположение в памяти нашего значения в качестве аргумента, который параметр (указатель, который выделяет пространство в памяти) в нашем Функция использует для указания значения.

Извини, что потерял это.

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

пример:

a = 5
double(a); <-- but this is pass-by-value
print a
end

function double(x) <-- x is a variable with a value of 5
    x = 2*x;
    print x;
    return x;

В приведенном выше примере значение 5 передается в double(). x в функции становится 10, а 10 печатается. Функция возвращается, и 5 печатается. поскольку aЗначение (не его адрес) было передано в double(), где double () не может изменить значение a,

Если бы мы передали указатель на a (передать по ссылке), не было бы проблемой изменить значение a,

При передаче по значению значение в адресе вычисляется и передается во время выполнения. но при передаче по ссылке никакое значение не определяется, только адрес передается функции, которую вы сами считываете значение и вносите изменения непосредственно в ячейку памяти, а не в значение, которое передается вам, как при передаче по значению, это очень низкий уровень и может привести к проблемам, потому что, если одна или несколько программ одновременно выполняют операции с ячейкой памяти, это может быть неоднозначностью. Это одна из причин, по которой java не поддерживает указатели.

При передаче по значению данные в ячейке памяти не изменяются, пока ваша функция выполняет операции. Потому что он выполняет операции над его копией. Что-то вроде многопоточности в Java.

Другие вопросы по тегам