"Параметры, передаваемые по значению" Алгоритмы CLRS - PullRequest
0 голосов
/ 11 ноября 2019

Что авторы подразумевают под выражением «данные, представляющие объект, копируются, а атрибуты объекта - нет», кто-то дает мне пример того, как это работает на практике, возможно, в python, java или C?


Ниже приводится выдержка из первой главы алгоритмов CLRS.

"Мы передаем параметры в процедуру по значению: вызываемая процедура получает свою собственную копию параметров, и если онаприсваивает значение параметру, изменение не видится вызывающей процедурой. При передаче объектов указатель на данные, представляющие объект, копируется, а атрибуты объекта - нет. Например, если x является параметромВ вызываемой процедуре присваивание x = y в вызываемой процедуре невидимо для вызывающей процедуры. Однако присваивание xf = 3 является видимым. Точно так же массивы передаются по указателю, так что указатель на массив передается скореечем весь массив, и изменения отдельных элементов массива видны to процедура вызова "

Заранее спасибо за помощь в решении этой проблемы.

1 Ответ

0 голосов
/ 11 ноября 2019

Это нормальное поведение практически всех современных императивных языков программирования, которые имеют неизменяемые примитивы и изменяемые объекты, такие как Java, Python, Javascript и т. Д. Я буду использовать Javascript для примеров, но если вы не знаете Javascript, надеюсь, код достаточно прост, чтобы вы все равно поняли объяснение.


Рассмотрим следующий код, который объявляет переменную и вызывает функцию:

function foo(x) {
    x = 5;
}

var y = 2;
foo(y);
console.log(y); // outputs number 2

Переменная x внутри функции получает свое значение из y, но это другая переменная, хранящаяся в другом месте в памяти. Поэтому, когда функция назначает число 5 для x, число 5 равно , а не , также назначаемому y;изменение в x не «видно» вне функции.

Теперь рассмотрим этот код, который по сути такой же, только с объектом вместо числа:

function bar(x) {
    x = { a: 3, b: 4 };
}

var y = { a: 1, b: 2 };
bar(y);
console.log(y); // outputs { a: 1, b: 2 }

Снова, x получает свое значение от y (который является ссылкой на объект), но назначение новой ссылки на x не меняет, какая ссылка y хранится, потому что они хранятся в разных местах памяти.

Теперь последний пример:

function baz(x) {
    x.a = 3;
    x.b = 4;
}

var y = { a: 1, b: 2 };
baz(y);
console.log(y); // outputs { a: 3, b: 4 }

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


Если все это кажется вам простым, тогда вы можете проигнорировать абзац;это просто объясняет, что язык, который они используют в книге, имеет такое поведение. Цель этого параграфа - прояснить семантику их языка, потому что не все функции во всех языках ведут себя таким образом.

В C ++, например, можно написать foo и barтаким образом, что они будут изменять значение y "на расстоянии". Или в функциональном языке программирования, где объекты неизменны, baz не будет изменять объект y, вместо этого он будет создавать новые объекты с другими свойствами, которые не будут видны вне функции.

Таким образом, этот параграф в их книге является полезным разъяснением для читателей, которые могут быть более знакомы с этой другой семантикой для параметров функции.

...