Является ли PHP и C ++ единственными двумя местами, которые нам нужно тщательно продумать, так как передача по значению действительно является передачей по ссылке? - PullRequest
0 голосов
/ 02 июня 2009

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

например

$count = 2;
foo($count);
echo $count;

и 3-я строка echo $ count отображают что-то отличное от 2. Я знаю только PHP и C ++, где это может произойти. Есть ли другое место, где это может произойти?

Обновление: то есть то, что выглядит как «передача по значению», фактически является «передачей по ссылке». Если он передает объект в Java, Perl, PHP, Python и Ruby, он автоматически передается по ссылке, и значения переменных экземпляра объекта могут быть изменены. Как насчет передачи в не-объект?

Ответы [ 4 ]

1 голос
/ 02 июня 2009

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

void func(type & arg);

можно изменить и

void func(type arg);

не может. И обычно в C ++ это не будет ссылочный аргумент, если API не хочет, чтобы значение было изменено в первую очередь (выходной параметр).

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

Вы должны быть осторожны, только если язык делает это не ясно , если переменная передается по значению или по ссылке .

1 голос
/ 02 июня 2009

Многие другие языки поддерживают такие «передачи по ссылке» - Perl, Fortran, Pascal, Visual Basic, ...

Какие из них тебя волнуют, нам трудно сказать! -)

Edit: В вашем обновлении вы помещаете Java и Python в одну и ту же категорию, но это неправильно: вы не можете воспроизвести свой пример с помощью (Java):

  int count = 2;
  whatever(count);
  /* count here is CERTAIN to be still 2 */

или (Python):

count = 2
whatever(count)
# count here is CERTAIN to be still 2

Стиль Python и Java иногда называют «ссылкой на объект» (в отличие от «ссылкой на переменную»): то, что передано (или назначено), является ссылкой на объект (поэтому, если у объекта есть мутаторы, вызываемые могут вызывать вызываемый объект) эти мутаторы и, таким образом, изменяют объект), а НЕ в «переменную» (так что после вызова переменная, если таковая имеется, использовалась для передачи аргумента, по-прежнему ссылается на тот же объект, а не на другой объект). Это различие наиболее ясно видно с неизменяемыми объектами, такими как (в Java и Python) числа и строки.

0 голосов
/ 07 июня 2009

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

Либо вы передаете примитив по значению (понятно всем, кого я предполагал), либо передаете ссылку на объект по значению. Хорошо, я теперь понимаю, но рассмотрим следующий код на Perl.

sub addFoo {
  my ($arrayRef) = @_;
  push @{$arrayRef},"foo"; 
}

my @array = (1,2,3);
my $arrayRef; # FUTURE reference (equivalent to pointer C) to @array.

addFoo($arrayref = \@array); #1.
addFoo(\@array); #2.
addFoo($arrayRef); #3.

print join(" ",@array),"\n"; # result "1 2 3 foo foo foo\n";

Мой вопрос, если какой из трех альтернативных вызовов addFoo считается передачей по ссылке, а не передачей по ссылке? Кажется, что ответ номер три ясен, но я не могу сказать номер 1. # 2. как делают точно так же. По крайней мере, число 2 явно рассматривается как переход по ссылке на некоторых страницах man perl и веб-сайтах.

0 голосов
/ 02 июня 2009

В старые времена ФОРТРАН передавал константы по ссылке. Вы можете передать константу 2 подпрограмме, и подпрограмма может присвоить ей 3. Затем по возвращении этот код

x = 2 + 2

установит x на 6. Я не знаю, позволят ли современные компиляторы FORTRAN это случиться.

...