C/C++、 Java、 python、c# 、JavaScript、PHP参数传递方式简介
☆C/C++里传递函数参数的时候,传值还是传引用是函数声明的时候决定的。下面几种函数声明方法都很常见:
// 传值
void PassByValue(int a)
//传指针
void PassByPtr(int* a)
// 传引用
void PassByRef(int& a)
可以把C++中形参传指针也归类为传值,因为这里形参copy的是一个指针的副本,本质上还是传值,只不过和调用方的原始指针指向了同一块内存而已,所以函数内针对该内存进行的修改才会反应到外面,看起来像是“传引用”,弄清楚这点很重要。
参见:https://www.includehelp.com/cpp-tutorial/argument-passing-with-its-types.aspx
☆Java中方法参数传递方式是按值传递。
如果参数是基本类型,传递的是基本类型的字面量值的拷贝。
如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。
Java 到底是值传递还是引用传递?https://www.zhihu.com/question/31203609/answer/50992895
参见Java is Pass-by-Value, Dammit! 我靠!Java就是值传递!https://blog.csdn.net/FIRE_TRAY/article/details/50649569
关于对象引用要记住什么(What to remember about object references ):
Java总是按值传递参数变量。
Java中的对象变量总是指向内存堆中的实际对象。
可变对象的值在传递给方法时可以更改。
不可变对象的值不能更改,即使它被传递了一个新值。
“传递值”指传递值的副本。
“按引用传递”是指传递内存中变量的实际引用。
【参见Does
Java pass by reference or pass by value? https://www.infoworld.com/article/3512039/does-java-pass-by-reference-or-pass-by-value.html 的“What to remember about object references“部分,原文如下:
Java always passes parameter variables by
value.
Object variables in Java always point to
the real object in the memory heap.
A mutable object’s value can be changed
when it is passed to a method.
An immutable object’s value cannot be
changed, even if it is passed a new value.
“Passing by value” refers to passing a copy
of the value.
“Passing by reference” refers to passing
the real reference of the variable in memory.】
☆Python本质上只支持按值传递【注】,原理和Java一样,可以理解为“引用”本身是值。而Python所有变量都是引用,甚至包括所有的整数,如42,也是将“42”这个对象的引用传入。但是整数、字符串等都是“不可变”(immutable)的类型,a=2;
a=3实际上是创建一个新的对象“3”,把引用赋给a,而“2”这个对象仍然是2。你不能通过参数让另一个函数改变当前函数的局部变量。
如果传递的是可变对象,则调用者将看到被调用者对其做出的任何更改;凡是对原对象操作的函数,都会影响传递的实际参数;凡是生成了新对象的操作,都不会影响传递的实际参数。
【注:Python 中,实参是通过 按值调用 传递的[call by value],其 值 始终是对象 引用 而不是对象的值。
在函数被调用时,实际参数(实参)[ parameters (arguments)]会被引入被调用函数的本地符号表中;因此,实参是通过
按值调用 传递的[call by value],其 值 始终是对象 引用 而不是对象的值,如果传递的是可变对象,则调用者将看到被调用者对其做出的任何更改;凡是对原对象操作的函数,都会影响传递的实际参数;凡是生成了新对象的操作,都不会影响传递的实际参数。
参见 https://docs.python.org/zh-cn/3.9/tutorial/controlflow.html#more-on-defining-functions】
在 C# 中,实参可以按值或按引用传递给形参。
https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters
JavaScript(JS)中函数的参数传递方式都是按值传递,没有按引用传递。
当传递原始类型值给形参时,传递的就是原始值本身。当传递引用类型值给形参时,传递的是一个指针(一个特殊的值)。
JS在访问变量时有按值和按引用两种方式,但参数只会按值传递。
JS传递基本类型的参数时,传递的是变量的复制,在函数作用后,被传递的变量并不受到影响。而传递引用类型的变量时,传递的是引用变量的内存地址,所以在函数作用后引用类型变量会受到函数作用。这跟 Java 类似,只有按值传递,但是值类型和引用类型,表现有所不同,所以造成人误以为引用类型是按引用传递了。
深入理解 JS 参数传递 https://xie.infoq.cn/article/fa86ad380a594d10970dc1c6f
PHP 支持按值( by value)传递参数(默认),引用( by reference)传递参数 https://www.php.net/manual/en/functions.arguments.php
附录:
C语言中函数参数传递的三种方式 https://blog.csdn.net/weibo1230123/article/details/75541862
go语言中函数参数传值还是传引用的思考 https://cloud.tencent.com/developer/article/1416563
C和CPP的区别 & C++,Java and Python的区别 https://developer.aliyun.com/article/11729
JavaScript中函数的参数传递方式都是按值传递 https://segmentfault.com/q/1010000003023316
JavaScript函数参数的传递方式详解 https://www.jb51.net/article/107586.htm
为什么说java只有按值传递 https://www.codenong.com/cs109706152/
Does Java “pass-by-reference” or “pass-by-value”? https://stackabuse.com/does-java-pass-by-reference-or-pass-by-value/
Discussion about Parameter Passing in C/C++/Java/C# https://www.researchgate.net/publication/280580876_Discussion_about_Parameter_Passing_in_CCJavaC