精华内容
下载资源
问答
  • 本文通过实例代码给大家介绍了Java中的按值传递和按引用传递的相关知识,感兴趣的朋友跟随脚本之家小编一起学习吧
  • 深入理解--Java按值传递和按引用传递

    万次阅读 多人点赞 2017-07-20 15:48:49
    引言最近刷牛客网上的题目时碰到不少有关Java按值传递和按引用传递的问题,这种题目就是坑呀,在做错了n次之后,查找了多方资料进行总结既可以让自己在总结中得到提高,又可以让其他人少走弯路。何乐而不为?Java按...

    引言

    最近刷牛客网上的题目时碰到不少有关Java按值传递和按引用传递的问题,这种题目就是坑呀,在做错了n次之后,查找了多方资料进行总结既可以让自己在总结中得到提高,又可以让其他人少走弯路。何乐而不为?

    Java按值传递和按引用传递

    首先问一句:Is Java “pass-by-reference” or “pass-by-value”? Java到底是按值传递还是按引用传递的呢?国外的网站上关于这个问题的讨论非常之多。官方答案:The Java Spec says that everything in Java is pass-by-value. There is no such thing as “pass-by-reference” in Java. 官方的说法是在java中只有按值传递,并没有所谓的按引用传递。

    基本数据类型的按值传递

    java数据类型可以分为两大类:基本类型(primitive types)和引用类型(reference types)。primitive types 包括boolean类型以及数值类型(numeric types)。numeric types又分为整型(integer types)和浮点型(floating-point type)。整型有5种:byte short int long char(char本质上是一种特殊的int)。浮点类型有float和double。关系整理一下如下图:

    这里写图片描述
    例1

    public class Swap {
    
        public static void main(String[] args) {
            int x = 10;
            int y = 20;
            swap(x, y);
            System.out.println("x(2) = " + x);
            System.out.println("y(2) = " + y);
        }
         public static void swap(int x, int y) {
            int temp = x;
            x = y;
            y = temp;
            System.out.println("x(1) = " + x);
            System.out.println("y(1) = " + y);
        }
    }
    
        /*输出
        x(1) = 20
        y(1) = 10
        x(2) = 10
        y(2) = 20
        */

    上面程序main函数调用swap函数来交换 x,y的值,然而调用函数之后发现main中x,y的值并未交换。包括在Java api中找不到一个可以交换两个变量的方法。这与Java语言的特性有关。通过一个图就可以知道上面程序的运行结果了。

    这里写图片描述
    由上图可知,main函数中的x,y和swap函数中的x,y分别存放在不同的区域,在main中调用swap函数的时候,会将main中的x,y的值赋给swap中的x,y。当swap函数中对x,y交换时只是对swap帧中的x,y做交换,并不会改变main中的x,y。所以当函数返回时main中的x,y并不会改变。swap执行过程图如下:
    这里写图片描述

    对于基本数据类型 short int long float double char byte boolean这八种按值传递调用函数并不会改变在原函数中的值。

    引用数据类型的按值传递

    引用数据数据类型分为三种:①接口 ②类 ③数组对于引用数据类型的按值传递先给出一个实例对比实例进行分析。

    例2

    public static void main(String[] args) {    
            int []a={10,20};
            System.out.println("a[0] :"a[0]+"a[1] : "+a[1]);//a[0]=10,a[1]=20;      
            swap(a, 0, 1);
            System.out.println("a[0] :"a[0]+"a[1] : "+a[1]);//a[0]=20,a[1]=10;  
    
        }
    public static void swap(int []a,int i,int j){
            int temp=a[i];
            a[i]=a[j];
            a[j]=temp;
            System.out.println("a[0] :"a[0]+"a[1] : "+a[1]);//a[0]=20,a[1]=10;
        }
    //输出
    /*a[0]=10 a[1]=20
    
      a[0]=20 a[1]=10
    
      a[0]=20 a[1]=10   
    */

    运行程序后发现,swap函数对a[0] ,a[1]的操作竟然影响到了main函数中的a[0] ,a[1]的值,真是不可思议。为什么会产生如此之结果。原来引用类型的按值传递,传递的是对象的地址。还是用图来解释一下。

    这里写图片描述
    由图可以看出在swap中仅仅是得到了数组的地址,并没有对数组的元素进行复制,在swap中对数组的操作是直接对main函数中数组的操作,因此swap函数返回后main函数中的a[0] ,a[1]的值发生交换。

    数组、类、接口按值传递的时候都是传递对象的地址。再来看一个比较复杂的实例。

    例3

    public class Main{
         public static void main(String[] args){
              Foo f = new Foo("f");
              changeReference(f); // It won't change the reference!
              modifyReference(f); // It will modify the object that the reference variable "f" refers to!
         }
         public static void changeReference(Foo a){
              Foo b = new Foo("b");
              a = b;
         }
         public static void modifyReference(Foo c){
              c.setAttribute("c");
         }
    }

    ①Foo f = new Foo(“f”);
    这里写图片描述

    ②public static void changeReference(Foo a)
    这里写图片描述

    ③changeReference(f);
    这里写图片描述

    ④Foo b = new Foo(“b”);
    enter image description here
    ⑤a = b
    enter image description here

    enter image description here
    ⑥c.setAttribute(“c”);

    enter image description here

    经典笔试题目

    试题1

    public class Demo {
    
        public static void main(String[] args) {
    
            //demo1
            String str=new String("hello");
            char []chs={'w','o','r','l','d'};
            change(str, chs);
            System.out.println(str+" "+new String(chs));
    
            //-------------------------------------------------
            //demo2
    
            StringBuffer sb=new StringBuffer("hello");
            change(sb);
            System.out.println(sb);
    
        }
        public static void change(StringBuffer sb)
        {
            sb.append(" world");
    //      sb.deleteCharAt(0);
        }
        public static void change(String str,char[]chs)
        {
            str.replace('h', 'H');
            chs[0]='W';     
        }       
    }

    上面程序段demo1和demo2分别输出什么,这里涉及到String特性,这道题目会做了,Java按值传递和按引用传递就彻底懂了,答案和解析先匿了。

    试题2

    public class foo {
        public static void main(String sgf[]) {
    
            StringBuffer a=new StringBuffer(“A”);
            StringBuffer b=new StringBuffer(“B”);
            operate(a,b);
            System.out.println(a+”.”+b);
    
        }
    
        static void operate(StringBuffer x,StringBuffer y) {
    
            x.append(y);
            y=x;
    
        }
    }

    参考文献

    1.https://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value

    展开全文
  • 主要介绍了Java按值传递和按址传递(面试常见)知识,在面试笔试题中经常会遇到,今天小编给大家详细介绍下,需要的朋友可以参考下
  • Java:按值传递还是按引用传递详细解说
  • Js引用类型按值传递的题目:两个变量间赋值时,以及作为变量给函数传参时,只是将原变量中的值复制一个副本给对方变量或形参变量 i. 对于原始类型的值,修改新变量,不影响原变量 ii. 对于引用类型的值的值,因为...
  • 值传递和引用传递详解:1:值传递是什么指的是在方法调用时,传递的参数是值的拷贝传递。示例如下:publicclassTempTest{privatevoidtest1(inta){//做点事情}publicstaticvoidmain(String[]args){TempTestt=...

    值传递和引用传递详解:

    1:按值传递是什么

    指的是在方法调用时,传递的参数是按值的拷贝传递。示例如下:

    public class TempTest {

    private void test1(int a){

    //做点事情

    }

    public static void main(String[] args) {

    TempTest t = new TempTest();

    int a = 3;

    t.test1(a);//这里传递的参数a就是按值传递

    }

    }

    按值传递重要特点:传递的是值的拷贝,也就是说传递后就互不相关了。

    示例如下:

    public class TempTest {

    private void test1(int a){

    a = 5;

    System.out.println("test1方法中的a="+a);

    }

    public static void main(String[] args) {

    TempTest t = new TempTest();

    int a = 3;

    t.test1(a);//传递后,test1方法对变量值的改变不影响这里的a

    System.out.println(”main方法中的a=”+a);

    }

    }

    运行结果是:

    test1方法中的a=5

    main方法中的a=3

    2:按引用传递是什么

    指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。

    示例如下:

    public class TempTest {

    private void test1(A a){

    }

    public static void main(String[] args) {

    TempTest t = new TempTest();

    A a = new A();

    t.test1(a); //这里传递的参数a就是按引用传递

    }

    }

    class A{

    public int age = 0;

    }

    3:按引用传递的重要特点

    传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间)。

    示例如下:

    public class TempTest {

    private void test1(A a){

    a.age = 20;

    System.out.println("test1方法中的age="+a.age);

    }

    public static void main(String[] args) {

    TempTest t = new TempTest();

    A a = new A();

    a.age = 10;

    t.test1(a);

    System.out.println(”main方法中的age=”+a.age);

    }

    }

    class A{

    public int age = 0;

    }

    运行结果如下:

    test1方法中的age=20

    main方法中的age=20

    4:理解按引用传递的过程——内存分配示意图

    要想正确理解按引用传递的过程,就必须学会理解内存分配的过程,内存分配示意图可以辅助我们去理解这个过程。

    用上面的例子来进行分析:

    (1):运行开始,运行第8行,创建了一个A的实例,内存分配示意如下:

    5927733.html

    5927733.html

    1352904793_7656.jpg

    (2):运行第9行,是修改A实例里面的age的值,运行后内存分配示意如下:

    1352904854_9920.jpg

    (3):运行第10行,是把main方法中的变量a所引用的内存空间地址,按引用传递给test1方法中的a变量。请注意:这两个a变量是完全不同的,不要被名称相同所蒙蔽。

    内存分配示意如下:

    5927733.html

    1352904930_4435.jpg

    由于是按引用传递,也就是传递的是内存空间的地址,所以传递完成后形成的新的内存示意图如下:

    1352905063_4451.jpg

    也就是说:是两个变量都指向同一个空间。

    (4):运行第3行,为test1方法中的变量a指向的A实例的age进行赋值,完成后形成的新的内存示意图如下:

    1352905129_9181.jpg

    此时A实例的age值的变化是由test1方法引起的

    (5):运行第4行,根据此时的内存示意图,输出test1方法中的age=20

    (6):运行第11行,根据此时的内存示意图,输出main方法中的age=20

    5:对上述例子的改变

    理解了上面的例子,可能有人会问,那么能不能让按照引用传递的值,相互不影响呢?就是test1方法里面的修改不影响到main方法里面呢?

    方法是在test1方法里面新new一个实例就可以了。改变成下面的例子,其中第3行为新加的:

    public class TempTest {

    private void test1(A a){

    a = new A();//新加的一行

    a.age = 20;

    System.out.println("test1方法中的age="+a.age);

    }

    public static void main(String[] args) {

    TempTest t = new TempTest();

    A a = new A();

    a.age = 10;

    t.test1(a);

    System.out.println(”main方法中的age=”+a.age);

    }

    }

    class A{

    public int age = 0;

    }

    运行结果为:

    test1方法中的age=20

    main方法中的age=10

    为什么这次的运行结果和前面的例子不一样呢,还是使用内存示意图来理解一下

    6:再次理解按引用传递

    (1):运行开始,运行第9行,创建了一个A的实例,内存分配示意如下:

    1352905341_1854.jpg

    (2):运行第10行,是修改A实例里面的age的值,运行后内存分配示意如下:

    1352905439_6900.jpg

    (3):运行第11行,是把main方法中的变量a所引用的内存空间地址,按引用传递给test1方法中的a变量。请注意:这两个a变量是完全不同的,不要被名称相同所蒙蔽。

    内存分配示意如下:

    1352905470_6545.jpg

    由于是按引用传递,也就是传递的是内存空间的地址,所以传递完成后形成的新的内存示意图如下:

    1352905527_3430.jpg

    也就是说:是两个变量都指向同一个空间。

    (4):运行第3行,为test1方法中的变量a重新生成了新的A实例的,完成后形成的新的内存示意图如下:

    1352905561_7018.jpg

    (5):运行第4行,为test1方法中的变量a指向的新的A实例的age进行赋值,完成后形成的新的内存示意图如下:

    1352905593_3787.jpg

    注意:这个时候test1方法中的变量a的age被改变,而main方法中的是没有改变的。

    (6):运行第5行,根据此时的内存示意图,输出test1方法中的age=20

    (7):运行第12行,根据此时的内存示意图,输出main方法中的age=10

    7. 说明:

    1.对象就是传引用:按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本

    2.原始类型就是传值:按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本

    3.String,Integer, Double等immutable类型因为没有提供自身修改的函数,每次操作都是新生成一个对象,所以要特殊对待。可以认为是传值。

    Integer

    和 String 一样。保存value的类变量是Final属性,无法被修改,只能被重新赋值/生成新的对象。 当Integer

    做为方法参数传递进方法内时,对其的赋值都会导致 原Integer 的引用被

    指向了方法内的栈地址,失去了对原类变量地址的指向。对赋值后的Integer对象做得任何操作,都不会影响原来对象。

    参考:http://blog.csdn.net/zzp_403184692/article/details/8184751(前文)

    http://blog.csdn.net/fbysss/article/details/3082949(后文)

    谢谢原创们的经典总结!

    展开全文
  • 主要介绍了JS是按值传递还是按引用传递(推荐)的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
  • c语言值传递和引用传递 First of all, this article is NOT going to explain C++ references and pointers. If you are not clear on what these are then this is quite probably the wrong article for...

    c语言值传递和引用传递

    First of all, this article is NOT going to explain C++

    首先,本文不会解释C ++

    references and 引用pointers. If you are not clear on what these are then this is quite probably the wrong article for you and you really should probably go read 指针 。 如果您不清楚这些是什么,那么这可能对您来说是错误的文章,您真的应该去 here, 这里here or 这里here. 这里阅读。

    In C++ all arguments are passed to functions by value. In other words, a copy of the value is taken and that is what the function has to work with. If you want to modify the original value you must either pass a pointer or reference to the original value you wish to modify. Of course, even the pointer or reference are still passed by value. Pointers and references are just another C++ type and when they are passed around you do so by value.

    在C ++中,所有参数都按值传递给函数。 换句话说,将获取值的副本,这就是函数必须使用的值。 如果要修改原始值,则必须传递一个指针或引用要修改的原始值。 当然,即使指针或引用也仍然按值传递。 指针和引用只是另一种C ++类型,当它们传递给您时,它按值进行传递。

    Now, what about the case where we don't want to modify the value? There's no need to pass by reference or pointer, right? Wrong! Now, in the case of fundemental types it probably doesn't make a huge deal of difference since these are unlikely to be any more complicated that a pointer or reference type; howver, in the case of fully blown class objects, such as string, vector, map, set or any other (including your own class objects) it can make a huge difference. You see, passing by value can be very expensive both in terms of memory usage and performance (time / space complexity)

    现在,如果我们不想修改值呢? 不需要通过引用或指针传递,对吗? 错误! 现在,在基本类型的情况下,它可能并没有太大的区别,因为它们不太可能比指针或引用类型复杂。 但是,对于完全爆炸的类对象,例如stringvectormapset或任何其他类对象(包括您自己的类对象),它可能会产生巨大的影响。 您会发现,就内存使用量和性能( 时间/空间复杂度 )而言,按值传递可能会非常昂贵

    Classes have copy constructors, which are defined to facilitate the correct copying semantics for a class. Now in C++ there are two types of copy, shallow and deep. A shallow copy is where all the values of the class are copied but pointers are not followed. A deep copy is where pointers are followed and all the objects that they point to are also copied, thus creating a copy of all the "deep" objects, too. Any class that contains references to other objects should (unless there is a very good reason not to) provide both an assignment and copy constructor such that the class is always copied deeply.

    类具有复制构造函数 ,该复制构造函数被定义为促进类的正确复制语义。 现在,在C ++中,有两种类型的复制, shallowdeep 。 浅表副本是复制类的所有值但不跟随指针的地方。 深度复制是指跟随指针的地方,指针所指向的所有对象也将被复制,从而也创建了所有“深度”对象的副本。 任何包含对其他对象的引用的类都应该(除非有很好的理由不这样做)同时提供分配和复制构造函数,以使该类始终被深深复制。

    Consider the std::vector class. This class contains an internal buffer of memory that is managed by the vector. In reality, we can assume that the vector contains a pointer that points to memory allocated on the heap. The vector class implements a copy constructor that will perform a deep copy on a vector object if a copy is taken. This is the only sane thing to do, otherwise we have two objects referencing the same memory and then we have issues of ownership. In other words, which of the vectors is now responsible for managing and freeing that memory and what happens to the other vector if that memory is released? Of course, it'll be left with a dangling pointer that is referencing invalid memory! Bad mojo for all!!!

    考虑一下std :: vector类。 此类包含由向量管理的内部内存缓冲区。 实际上,我们可以假定向量包含一个指向堆上分配的内存的指针。 vector类实现了一个复制构造函数,如果进行了复制,则该复制构造函数将在vector对象上执行深层复制。 这是唯一明智的操作,否则我们有两个引用相同内存的对象,然后出现所有权问题。 换句话说,哪个向量现在负责管理和释放该内存,如果释放了该内存,另一个向量会发生什么? 当然,它会留下一个指向无效内存的悬空指针 ! 所有人的坏魔力!

    Now, imagine we have a vector class that contains thousands of items. If we pass this object to a function by value the whole of the internal buffer will be copied. Not only is this really very inefficient in terms of the time it will take to allocate the memory and copy the values from the original vector to the copy it also increases memory usage greatly and, as a side effect, the risk of memory fragmentation. Imagine if this same vector is copied around again and again (maybe in a loop); it should be pretty clear just how inefficient this is.

    现在,假设我们有一个包含数千个项目的向量类。 如果我们通过值将该对象传递给函数,则将复制整个内部缓冲区。 这不仅在分配内存和将值从原始向量复制到副本所需的时间上确实非常低效,而且还大大增加了内存使用量,并且副作用是内存碎片化的风险。 想象一下,是否一次又一次地(也许是循环地)复制了相同的向量; 应该很清楚这是多么低效。

    The solution is to pass things around by const reference (or const pointer in C). The cost of passing things around by const reference is trivial and about as expensive as passing around an int value. Not only is it so much more efficient to pass objects in this way, but the semantics of your function become way clearer. Just looking at the function prototype tells us that the value being passed is never meant to be modified by this function. You are helping to enforce your objects interface contract.

    解决方案是通过const引用(或C中的const指针)传递内容。 通过const引用传递事物的成本是微不足道的,并且与传递int值一样昂贵。 以这种方式传递对象不仅效率更高,而且函数的语义也变得更加清晰。 仅查看函数原型就可以告诉我们,传递的值绝不会被该函数修改。 您正在帮助执行对象接口合同

    Let's see a trivial example. 

    让我们来看一个简单的例子。

    #include <vector>
    #include <chrono>
    #include <iostream>
    
    void foo(std::vector<int> byValue)
    {
    // do nothing
    }
    
    void bar(std::vector<int> const & byRef)
    {
    // do nothing
    }
    
    int main()
    {
       auto && v = std::vector<int>(0x7FFFFFF);
    
       auto && x1 = std::chrono::steady_clock::now();
       foo(v);
       auto && x2 = std::chrono::steady_clock::now();
       bar(v);
       auto && x3 = std::chrono::steady_clock::now();
    
       auto && d1 = std::chrono::duration_cast<std::chrono::nanoseconds>(x2 - x1);
       auto && d2 = std::chrono::duration_cast<std::chrono::nanoseconds>(x3 - x2);
    
       std::cout
             << "Time to call foo: " << d1.count() << std::endl
             << "Time to call bar: " << d2.count() << std::endl;
    }
    

    When running this on my Windows 7 laptop, build with Visual Studio 2013 and executed in as a Release build the call by value takes approximately 1 second whilst the call by reference takes less than a nanosecond. That makes the pass by value a billion times slower! Of course, this is a contrived example and on different machines with different compilers YMMV, but hopefully it serves to demonstrate just how slow passing by value can, when compared to passing by reference!

    在我的Windows 7笔记本电脑上运行此程序时,使用Visual Studio 2013进行构建并作为Release版本执行,按值调用大约需要1秒钟,而按引用调用则需要不到1纳秒。 这使传值速度降低了十亿倍! 当然,这是一个人为的示例,并且在具有不同编译器YMMV的不同机器上,但希望它能证明与按引用传递相比,按值传递可以有多慢!

    In the case of passing by value the cost in terms of both time and space complexity is O(N), where N is the number of bytes to be copied. Passing by reference will cost O(1), which is a significant improvement. Okay, the pedants amongst you may wish to argue that even for a reference it's O(N), because a reference is composed of bytes. True, but the big (massive) difference that the size of a reference is always constant and will be in the order of a few bytes (4 on a 32 bit machine, 8 on a 64 bit machine) and not hundreds, thousands, millions or even billion in the case of non-fundamental objects.

    在按值传递的情况下, 时间和空间复杂度方面的成本均为O(N),其中N是要复制的字节数。 通过引用传递将花费O(1),这是一个重大改进。 好的,你们中间的学徒可能会争辩说,即使对于引用,它也是O(N),因为引用是由字节组成的。 的确如此,但是最大的(巨大的)区别是引用的大小始终是恒定的,并且大约是几个字节(32位计算机上为4,64位计算机上为8),而不是数百,数千,数百万对于非基本物体,甚至是十亿。

    Note: that some compilers may optimize out the calls to the functions foo and bar due to the fact they don't do anything. This is most likely to happen if you have aggressive optimisation enabled on your compiler. You can either disable this or add some code to these functions to make use of the passed references. Whilst disabling optimisation may skew the results in an absolute sense, the relative comparison should still hold up because what we're truly interested in here is the asymtoptic variance (Big O) rather than wall clock time!

    注意:有些编译器可能会不执行任何操作,因此可能会优化对foo和bar函数的调用。 如果在编译器上启用了积极的优化,则最有可能发生这种情况。 您可以禁用此功能,也可以向这些功能添加一些代码以利用传递的引用。 尽管禁用优化可能会在绝对意义上扭曲结果,但相对比较仍然应该成立,因为我们真正感兴趣的是渐近方差(Big O),而不是挂钟时间!

    Further reading:

    进一步阅读:

    • Passing arguments by value

      通过传递参数
    • Passing arguments by reference

      通过引用传递参数
    • Passing arguments by address (pointer)

      通过地址 (指针)传递参数

    翻译自: https://www.experts-exchange.com/articles/18343/C-Passing-by-value-vs-passing-by-reference.html

    c语言值传递和引用传递

    展开全文
  • Python函数参数:按值传递和按引用传递

    千次阅读 多人点赞 2019-04-15 09:54:04
    首先简单说明一下,Python中按值传递按引用传递的区别: 值参数传递是指一个变量的值来取代一个函数参数的做法。 如果这个值在函数代码组中改变,对于调用这个函数的代码来说,其中相应的变量值并不会受到任何...

    首先简单说明一下,Python中按值传递与按引用传递的区别:

    按值参数传递是指一个变量的值来取代一个函数参数的做法。
    如果这个值在函数代码组中改变,对于调用这个函数的代码来说,其中相应的变量值并不会受到任何影响,可以把这个参数认为是原变量值的一个副本。


    按引用参数传递是指对于调用这个函数的代码,会维护这个代码中变量的一个链接(引用)。
    如果函数代码组中的变量改变,那么在调用这个函数的代码中,相应的变量值也会改变,可以把这个参数认为是原变量的一个别名。

    函数按值调用

    def double(arg):
    	print('Before:', arg)
    	arg = arg * 2
    	print('After:', arg)
    
    num = 10
    double(num)
    print('num:', num)
    saying = 'Hello'
    double(saying)
    print('saying:', saying)
    

    运行上述代码,输出结果如下:

    Before: 10
    After: 20
    num: 10
    Before: Hello
    After: HelloHello
    saying: Hello

    分析
    每次调用都确认了作为参数传入的值在函数代码组已经改变,但是在函数外部print出来的值仍保持不变。
    也就是说,函数参数看起来遵循按值调用语义。


    函数按引用调用

    def change(arg):
    	pring('Before:', arg)
    	arg.append('More data')
    	print('After:', arg)
    
    numbers = [42, 256, 16]
    change(numbers)
    print(numbers)
    

    运行上述代码,输出结果如下:

    Before: [42, 256, 16]
    After: [42, 256, 16, ‘More data’]
    numbers: [42, 256, 16, ‘More data’]

    分析
    这一次不仅函数中的参数值改变了,函数外部print出来的值也改变了。
    看起来说明Python函数也支持按引用调用语义。


    Python函数参数支持按值还是按引用传递?

    根据具体情况,Python的函数参数支持按值传递支持按引用传递

    实际上,解释器会查看对象引用(内存地址)指示的那个值的类型,如果变量指示一个可变的值,就会按引用调用语义。如果所指示的数据的类型是不可变的,则会应用按值调用语义。

    列表 字典 集合
    总是会按引用传入函数,函数代码组中对变量数据结构的任何改变都会反映到调用代码中

    字符串 整数 元组
    总是会按值传入函数,函数中对变量的任何修改是这个函数私有的,不会反映到调用代码中

    展开全文
  • 在分析这个问题之前,我们需了解什么是按值传递(call by value),什么是按引用传递(call by reference)。在计算机科学里,这个部分叫求值策略(Evaluation Strategy)。它决定变量之间、函数调用时实参形参之间值是...
  • 另一方面,值传递由于形参实参内存地址不一样,有些功能并不能实现(swap()),因此,除了极为简单的函数会使用值传递外,大多数会采用引用传递。而对于指针传递,则在涉及数组的情况下使用较多,因为指针本身会给...
  • 主要介绍了JavaScript中的值是按值传递还是按引用传递问题探讨,本文讲解了按值传递按引用传递、共享传递、基本类型的不可变(immutable)性质等内容,需要的朋友可以参考下
  • JavaScript有5种基本的数据类型,分别是:布尔、null、undefined、String和Number。这篇文章主要介绍了JavaScript的值传递和引用传递,需要的朋友可以参考下
  • 主要介绍了JAVA参数传递方式,结合实例形式分析了java按值传递引用传递区别及相关操作注意事项,需要的朋友可以参考下
  • 主要介绍了解析Java按值传递还是按引用传递,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • 测试数组作为参数传递给函数,在函数中访问修改。并且,这表明C语言的数组作为参数传递给函数时,是作为引用方式传递的。 还有,在传递的时候,还需要把数组的大小也一并传递给函数。因为只传递数组给函数,进而想...
  • JAVA参数传递方式 (按值传递引用传递区别)

    千次阅读 多人点赞 2018-09-30 22:58:30
    首先要明确的是JAVA中没有引用传递, 全部是按值调用 令大家所费解的 当对象引用作为参数时 函数为什么能修改真实的对象呢?这不是引用传递的特征吗? 尤其先学习C++再学习JAVA的同学(比如说我自己)会这样认为, 用...
  • Java的按值传递和按引用传递分析.rar
  • Java的按值传递和按引用传递分析 Java的按值传递和按引用传递分析.pdf
  • 主要介绍了 Java 值传递和引用传递详解及实例代码的相关资料,需要的朋友可以参考下
  • 请看一道选择题下列关于按值传递按引用传递的描述中,正确的是( )。A.按值传递不会改变实际参数的数值 B.按引用传递能改变实际参数的参考地址C.按引用传递能改变实际参数的内容 D.引...
  • 以js为例解释按值传递和按引用传递

    千次阅读 2018-02-01 23:27:42
    首先“ EMCAJavaScrip里面所有函数的参数传递都是按值传递” 这句话是公认的,没错的。 按值传递的意思就是形参是实参的复制。 按引用传递是 函数的形参接收实参的隐式引用,而不再是副本。这意味着函数形参的值...
  • 主要介绍了java通过实例了解值传递和引用传递,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 以下是对C#中按引用传递与按值传递的区别,以及ref与out关键字的用法进行了详细的分析介绍,需要的朋友可以过来参考下
  • 如果数据对象小,如内置数据类型或小型结构,则按值传递; 如果数据对象是数组,则使用指针,因为这是唯一的选择,并将指针声明为指向const的指针; 如果数据对象是较大的结构,则使用const指针或const引用,以...
  • 按值传递按引用传递详细解说

    千次阅读 2018-05-21 20:59:03
    1:按值传递是什么指的是在方法调用时,传递的参数是值的拷贝传递。示例如下:public class TempTest { private void test1(int a){ //做点事情 } public static void main(String[] args) { TempTest t = ...
  • C/C++按值传递和按地址传递

    万次阅读 多人点赞 2018-04-06 19:41:11
    C/C++的按值传递和按地址传递有明显不同,下面对他们作个区别:按值传递:在调用函数中将原函数的值拷贝一份过去被调用的函数,在被调用函数中对该值的修改不会影响原函数的值。按地址传递:在调用函数的时候将原...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,841,244
精华内容 736,497
关键字:

按值传递和按引用传递