首页 > 其他分享 >值传递和引用传递问题

值传递和引用传递问题

时间:2023-02-04 22:12:12浏览次数:41  
标签:问题 函数 int 函数调用 name 传递 引用 String

一、堆、栈

举个栗子:

int age = 22;
String name = new String("shuaibei");

这两个变量存储图如下:

img

如果,我们分别对agename变量赋值,会发生什么呢?

age = 18;
name = new String("xiaobei");

如下图:

img

age 仅仅是将栈上的值修改为 18,而 name 由于是 String 引用类型,所以会重新创建一个 String 对象,并且修改 name,让其指向新的堆对象。(细心的话,你会发现,图中 name 执行的地址我做了修改)

然后,之前那个对象如果没有其它变量引用的话,就会被垃圾回收器回收掉。

这里也要注意一点,我创建 String 的时候,使用的是 new,如果直接采用字符串赋值,比如:

String name = "shuaibei"

那么是会放到 JVM 的常量池去,不会被回收掉,这是字符串两种创建对象的区别,不过这里我们不关注。

Java 中引用这东西,和 C/C++ 的指针就是一模一样的嘛,只不过 Java 做了语义层包装和一些限制,让你觉得这是一个引用,实际上就是指针。

好,让我继续了解下函数调用栈。

二、函数调用栈

一个函数需要在内存上存储哪些信息呢?

参数、局部变量,理论上这两个就够了,但是当多个函数相互调用的时候,就还需要机制来保证它们顺利的返回和恢复主调函数的栈结构信息。

那这部分就包括返回地址、ebp寄存器(基址指针寄存器,指向当前堆栈底部) 以及其它需要保存的寄存器。

所以一个完整的函数调用栈大概长得像下面这个样子:

img

那,多个函数调用的时候呢?

简单来说就是叠罗汉,这是两个函数栈:

img

今天,我们不会去详细了解函数调用过程ebpebp如何变化,返回地址又是如何起作用的。

今天的任务就是搞明白参数传递,所以其它的都是非主线的知识,忽略即可。

顺便插点题外话:

学习新知识有时候需要刨根问底,有时候却需要及时回头,尤其是计算机,你要是一直刨根问题,我能给你整到硅的提纯去,这就是失去了学习的意义。

最好的方式是,在一个恰到好处的地方建立一个抽象层,并且认可这个抽象层提供的功能/接口,不去探究这一层下面是什么,怎么实现的。

比如,学习 HTTP,我就只需要认 TCP 提供稳定、可靠传输就够了,暂时就不需要去看 TCP 如何做到的。

好了,继续说回函数传参,举个例子,下面这段代码在main函数内调用了func_a函数

int func_a(int a, int *b) {
a = 5;
*b = 5;
};

int main(void) {
int a = 10;
int b = 10;
func_a(a, &b);
printf("a=%d, b=%d\n", a, b);
return 0;
}

// 输出
a=10, b=5

那么func_a(a, &b) 这个过程,在函数调用栈上究竟是怎么样的呢?

img

就像上图所示,编译器会生成一段函数调用代码。

main 函数内变量 a 的值拷贝到 func_a 函数参数 a 位置。

将变量 b的地址,拷贝到 func_a 函数参数 b 的位置。

记住这张图,这是函数参数传递的本质,没有其它方式,just copy!

copy 意味着是副本,也就是在子函数的参数永远是主调函数内的副本。

决定是值传递还是所谓的引用传递,在于你 copy 的到底是一个值,还是一个引用(的值)。

其实引用也是值......不要觉得引用就是那种玄乎的东西。

所以会有一种声音说,是不存在所谓的引用传递的,一切传引用的本质还是传值。

也就是 pass pointer by value 或者 pass reference by value,哈哈哈有点意思。

今天,我们不讨论到底有没有传引用这个东西,这是一个个仁者见仁智者见智的问题。

我的目的呢,就是把参数传递这个过程给大家剖析下,至于到底是传值还是传引用,那就看大家怎么思考了。

三、pass by value in java

举个最简单的例子来说明下:

public class HelloWorld {
 
  public static void ChangeRef(String name) {
      name = new String("xiaobei");
  }

  public static void main(String[] args) {
      String name = new String("shuaibei");
      ChangeRef(name);
      System.out.println(name.equals("shuaibei"));

  }
}

上面,ChangeRef 函数实际上并没有改变到 main 函数内的 name 对象,看图就明白了:

img

根据我们前面所讲,参数传递实际就是复制栈上的值本身,这里name的值就一串地址,所以ChangeRef接收到的也是这串地址,但是在ChangeRef函数内将name的指向改成了一个新的 String 对象,但是这里不会对main函数中的 name 对象产生任何的影响。

咦,不是说引用类型都是引用传递吗?为什么还不会对主调函数产生影响呢?

我们都把引用的指向改变了,还能影响个啥,如果想通过引用传递修改外部传进来的值,一般是采用成员方法。

假设 String 类有一个方法叫做changeStr(String value),那么我们就可以在ChangeRef内调用这个方法,修改name的值,

并且会同步修改到main函数里的值。

(其实这里最好的说明方式是自己定义一个类,但是我懒了,就省掉了哈哈哈,相信聪明的你一定知道我在说什么~)

标签:问题,函数,int,函数调用,name,传递,引用,String
From: https://www.cnblogs.com/GO8k/p/17092513.html

相关文章

  • 向上和向下转型问题
    Java中对象类型之间的类型转换(前提是两个类是父子关系)1.向上转型:把子类对象直接赋给父类引用,自动进行类型转换。​静态方法/成员变量(包括静态变量和实例变量)同“父类引......
  • StringBuffer和StringBuilder问题
    在Java中字符串属于对象,Java提供了String类来创建和操作字符串。String类是不可变类,即一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至......
  • 解决vuepdf不显示章印问题
    找到node_modules/pdfjs-dist/es5/build/pdf.worker.js这个目录if(data.fieldType==="Sig"){data.fieldValue=null;//pdf预览不显示红章问题......
  • ChatGPT 有哪些神奇的使用方式?使用chargpt写代码 搜索问题 写论文
    本教程介绍chargpt使用教程:不需要梯子,不需要注册,也不需要缴纳费用通过本教程您将会使用chargpt写代码搜索问题写论文。我展示了两个问题问题一:用python写一个学生信......
  • nginx相关配置问题
    nginx常用功能http代理正向代理和反向代理Nginx可以根据不同的正则匹配,采取不同的转发策略,比如图片文件结尾的走文件服务器,动态页面走web服务器,只要你正则写的没问题,......
  • VisualStudio此扩展不能安装在任何当前安装的产品上/无法安装此扩展因为缺少以下引用(
    visualstudio扩展/样式/主题1、下载主题安装扩展ColorThemeEditorforVisualStudio主题下载地址IntroducingCollectionofNewVisualStudioThemes!-Visua......
  • netcore 部署问题集
    一、IIS    ①、x86部署问题1、错误信息(附截图):Couldnotfind'aspnetcorev2_inprocess.dll'.Exceptionmessage:2、错误信息(附截图):Failedtostartapplic......
  • 记一次使用gdb诊断gc问题全过程
    原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处。简介上次解决了GC长耗时问题后,系统果然平稳了许多,这是之前的文章《GC耗时高,原因竟是服务流量小?》然而,过了......
  • stream流中toMap()api和Duplicate key问题
    1、指定key-value,value是对象中的某个属性值。Map<Integer,String>userMap=userList.stream().collect(Collectors.toMap(User::getId,User::getName));2、指定key......
  • 一次因内存引用引发的数据重复的问题
    前言第一次使用expandablelistview,其中要创建一个二维的arraylist,但在使用过程中导致一直出现数据重复的状况,入图所示当独立打开一组并关闭其他组时,显示正常。但当打开......