Как я могу описать разницу между этими двумя стилями передачи значений? - PullRequest
0 голосов
/ 04 мая 2020

Это то, что, как я понимаю, передается по ссылке в C (примечание: я не C программист):

void foo(int* x) { // The value of the memory address passed into `foo` is copied into parameter `x`
  *x = 1; // The memory address x is dereferenced(?) and the value at that location overwritten
}

int main() {
  int a = 0;
  foo(&a); // The value of the (starting?) memory address associated with `a` is found and supplied as an argument to the function call
  // `a` is now `1`
}

Таким образом, независимо от типа x (даже если это объект (структура в C?)), изменения, сделанные в x внутри foo, будут отражены в области действия main, , даже если весь объект будет заменен .

В JavaScript примитивы просто копируются, и об этом достаточно просто рассуждать.

Но для объектов, IIU C, значение их адреса памяти (или эквивалент) передается в функцию foo, которая внешне звучит аналогично приведенному выше коду C. Однако, если мы присвоим значение идентификатору, созданному параметром x, это будет , а не , отраженное в области действия main.

function foo(x) {
  x = { bam: 'this is bam' }; // The value of the memory address passed into `foo` is copied into parameter `x`
}

function main() {
  let a = { bar: 'this is bar' };
  foo(a); // The value of the memory address associated with `a` is found and supplied as an argument to the function call (?)
  // `a` is unchaged
}

JavaScript передается ценность. Для объектов его иногда называют передачей по значению ссылки - достаточно справедливо - но в приведенном выше коде C значение ссылки (указатель ОК) также копируется в функцию. Итак, как я могу описать различия между передачей по ссылке и передачей по значению? Является ли передача значений на самом деле одинаковыми, но отличается только поведение ссылок / разыменования двух языков?

1 Ответ

1 голос
/ 04 мая 2020

C передает все по значению 1 . Иногда эти значения являются значениями указателя; это не то же самое, что передача по ссылке.

В истинной передаче по ссылочной системе формальный параметр в определении функции обозначает тот же объект, что и фактический параметр в вызове функции (при условии, что фактический параметр isn ' во всяком случае, цифра c). Достигается ли это с помощью указателей или под капотом, или с помощью другого механизма, зависит от реализации. Это не всегда так в C.

Выражение *x в foo обозначает тот же объект, что и выражение a в main, но формальный параметр x является отдельным объектом от a. Результат выражения &a передается по значению и сохраняется в уникальном объекте x.

 x == &a // int * == int *
*x ==  a // int   == int


Массивы странные. За исключением случаев, когда это операнд операторов sizeof или унарных & или строковый литерал, используемый для инициализации массива символов в объявлении, выражение типа "N-элементный массив типа T "будет преобразовано (" распад ") в выражение типа" указатель на T ", а значением выражения будет адрес первого элемента массива. Когда вы передаете выражение массива в качестве аргумента функции, функция получает указатель на первый элемент, а не копию всего массива. Таким образом, в отличие от других типов аргументов, изменения в содержании аргумента массива в функции отражаются в вызывающей стороне. Однако это все еще не совсем так. Это просто следствие несколько уникальной семантики массива C.
...