写点什么

细说值传递、引用传递和地址传递

作者:Barry Yan
  • 2022-11-29
    北京
  • 本文字数:1590 字

    阅读完需:约 5 分钟

细说值传递、引用传递和地址传递

1 实参和形参

形式参数:是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。


实际参数:在调用有参函数时,主调函数和被调函数之间有数据传递关系。在主调函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”。


func main() {   i := sum(2, 4) //2,4为实参   fmt.Println(i)}
func sum(a int, b int) int { //a,b为形参 c := a return b + c //a,b,c为形参}
复制代码

2 值传递、引用传递和指针传递:

值传递:指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。


引用传递:指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。


指针传递:指在调用函数时将实际参数的指针地址直接传递到函数中,类似于引用传递,最大不同就是指针指向的类型不能为 null。


指针传递和引用传递的不同:指针就是地址变量,所以引用相当于把地址常量作为参数,指针相当于把地址变量作为参数。

2.1 Go 语言演示

type Obj struct {   Id   int   Name string}
func main() { //值传递和引用传递测试 fmt.Println("值传递...") v1 := 2 v2 := Obj{2, "ls"} fmt.Println(v1, v2) updateVal(v1, v2) fmt.Println(v1, v2)
//指针传递测试 fmt.Println("指针传递...") v3 := 2 v4 := Obj{2, "ls"} fmt.Println(v3, v4) updateValPoint(&v3, &v4) fmt.Println(v3, v4)}
//值传递func updateVal(v1 int, v2 Obj) { v1 = 1 v2 = Obj{1, "zs"}}
//引用传递func updateValPoint(v1 *int, v2 *Obj) { *v1 = 12 *v2 = Obj{1, "zs"}}
复制代码


输出:


值传递...2 {2 ls}2 {2 ls}指针传递...2 {2 ls}12 {1 zs}
复制代码

2.2 Java 语言演示

public static void main(String[] args) {    System.out.println("值传递1");    int v1 = 2;    String v2 = "zz";    Obj v3 = new Obj(2, "ls");    System.out.println(v1 + "--" + v2 + "--" + v3);    updateValue(v1, v2, v3);    System.out.println(v1 + "--" + v2 + "--" + v3);
System.out.println("值传递2"); int v4 = 2; String v5 = "zz"; Obj v6 = new Obj(2, "ls"); System.out.println(v4 + "--" + v5 + "--" + v6); updateValuePoint(v4, v5, v6); System.out.println(v4 + "--" + v5 + "--" + v6);}
public static void updateValue(int v1, String v2, Obj v3) { v1 = 1; v2 = "ww"; v3 = new Obj(1, "zs"); v3.setId(1); v3.setName("zs");}
public static void updateValuePoint(int v1, String v2, Obj v3) { v1 = 1; v2 = "ww"; v3.setId(1); v3.setName("zs");}
@AllArgsConstructor@ToString@Datastatic class Obj { public int id; public String name;}
复制代码


输出:


2--zz--Main.Obj(id=2, name=ls)2--zz--Main.Obj(id=2, name=ls)2--zz--Main.Obj(id=2, name=ls)2--zz--Main.Obj(id=1, name=zs)
复制代码

3 总结下

在 Java 方法中参数列表有两种类型的参数,基本类型和引用类型。


基本类型:值存放在局部变量表中,无论如何修改只会修改当前栈帧的值,方法执行结束对方法外不会做任何改变;此时需要改变外层的变量,必须返回主动赋值。


引用数据类型:指针存放在局部变量表中,调用方法的时候,副本引用压栈,赋值仅改变副本的引用。但是如果通过操作副本引用的值,修改了引用地址的对象,此时方法以外的引用此地址对象当然被修改。(两个引用,同一个地址,任何修改行为 2 个引用同时生效)。


这两种类型都是将外面的参数变量拷贝一份到局部变量中,基本类型为值拷贝,引用类型就是将引用地址拷贝一份。


参考文章


https://www.cnblogs.com/lingyejun/p/11028808.html


https://blog.csdn.net/belongtocode/article/details/107713117

发布于: 2022-11-29阅读数: 33
用户头像

Barry Yan

关注

做兴趣使然的Hero 2021-01-14 加入

Just do it.

评论

发布
暂无评论
细说值传递、引用传递和地址传递_编程语言_Barry Yan_InfoQ写作社区