0

PHP 和 C++ 是我们在将简单数据类型变量作为函数参数传递并且值可以更改时唯一需要注意的两个地方吗?

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

第三行,echo $count 显示 2 以外的内容。我只知道 PHP 和 C++ 会在哪里发生。还有其他地方可以发生吗?

更新:也就是说,看起来像“按值传递”实际上是“按引用传递”。如果它在 Java、Perl、PHP、Python 和 Ruby 中传递对象,它会自动通过引用传递,并且可以更改对象的实例变量的值。那么传入非对象呢?

4

4 回答 4

1

许多其他语言都支持这种“通过引用”——Perl、Fortran、Pascal、Visual Basic,...

你关心哪些,好吧,我们很难说!-)

编辑:在您的更新中,您将 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 的风格有时被称为“通过对象引用”(与“通过变量引用”相反):传递(或分配)的是对对象的引用(因此,如果对象具有 mutators,则被调用者可以调用这些 mutators 和因此改变对象),而不是“变量”(这样在调用之后,用于传递参数的变量(如果有的话)仍然引用同一个对象,而不是另一个对象)。这种区别在不可变对象中最为明显,例如(在 Java 和 Python 中)数字和字符串。

于 2009-06-02T01:38:12.660 回答
1

除非您明确将其定义为引用,否则您无法更改 C++ 中的变量。如果您有常规(非参考)参数,它们是副本并且不能更改。如果您阅读并理解 API,则无需小心将简单的数据类型变量作为函数参数传递

void func(type & arg);

可以改变和

void func(type arg);

不能。通常在 C++ 中它不会是引用参数,除非 API 想要首先更改值(输出参数)。

正如亚历克斯已经提到的,有许多语言支持通过引用成语。

如果一种语言不清楚变量是按值传递还是按引用传递,您只需要小心。

于 2009-06-02T01:41:44.307 回答
0

回到过去,FORTRAN 通过引用传递常量。您可以将常量 2​​ 传递给子例程,而子例程可以为其分配 3。然后返回后,这段代码

x = 2 + 2

会将 x 设置为 6。我不知道现代 FORTRAN 编译器是否允许这种情况发生。

于 2009-06-02T03:47:11.197 回答
0

根据上面的讨论,最近我了解到 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。和做的完全一样。在某些 perl 手册页和网站中,至少数字 2 被明确视为传递引用。

于 2009-06-07T02:29:39.493 回答