zoukankan      html  css  js  c++  java
  • 编程语言在函数中的参数传递

    1、Python

    Python 的参数传递是赋值传递 (pass by assignment),或者叫作对象的引用传递(pass by object reference)。Python 里所有的数据类型都是对象,所以参数传递时,只是让新变量与原变量指向相同的对象而已,并不存在值传递或是引用传递一说。 ----来自互联网

    总结一下:就是在使用函数时,把实参赋给函数的形参,即形参=实参,函数的形参和实参指向同一对象。

    那么在函数中参数的变化只受其本身对象的性质影响了。

    Python中的数据类型有可变不可变,string这种不可变类型被修改后相当于重新赋值,句柄指向新的对象。

    传递string(不可变)

    def fun(a:str):
        print("2  ",id(a))
        a+="b"
        print("3   ",id(a))
    
    
    a="aa"
    print(id(a))
    
    fun(a)
    
    print(a)
    
    1753958904624 
    2   1753958904624    #传递前后是一个对象
    3    1753960317104   #string是不可变类型,修改了就是另一个对象
    aa 
    

    传递list(可变类型)

    def fun(a:list):
        print("2  ",id(a))
        a.append("1")
        print("3   ",id(a))
    
    
    a=['a','b']
    print(id(a))
    
    fun(a)
    
    print(a)
    
    2017284788416         #传递前后是一个对象
    2   2017284788416
    3    2017284788416   #list是可变类型,即使修改了,对象也没变
    ['a', 'b', '1']      
    

    2、JS

    JS和Python一样,也是直接把实参给了形参。

    string(不可变的值类型)

    function f(str) {
        console.log("内部:  ",str==="Hello World");
        str += "!";
        return str;
    }
    
    var str="Hello World";
    console.log("外部1: ",str==="Hello World");
    
    console.log("外部2:   ",str===f(str));
    
    
    外部1:  true
    内部:   true
    外部2:    false
    

    Array(引用类型)

    function f(arr2) {
       console.log(arr===arr2);
       arr2.push("!");
       console.log(arr===arr2);
    }
    
    var arr=[];
    arr.push("hello");
    arr.push("world");
    
    f(arr);
    
    console.log("数组: ",arr);
    
    true
    true
    数组:  [ 'hello', 'world', '!' ]
    

    3、Java

    Java的数据类型分为两种:基本类型和引用类型。

    引用类型分为下面几种:类类型(class,interface,enum,annotation)和数组类型 。

    Java也是赋值传递。

    int(基本类型)

    基本类型不需要new,赋值直接使用,修改了句柄就指向新的位置了。

    public class Args_ref {
    
    
        public static int f(int x){
            x+=1;
            return x;
        }
    
    
        
        public static void main(String[] args) {
            int x=10;
            int y=f(x);
            System.out.printf("x=%d, y=%d, x==y?%b",x,y,x==y);
    
        }
        
    }
    x=10, y=11, x==y?false
    

    数组(对象)

    数组是对象。

     	public static int[] ff(int[] x){
            System.out.println("ff hashCode: "+x.hashCode());
            if(x!=null){
                x[0]=100;    //修改一下x中的元素,也就是对原数组进行修改
            }
            return x;
        }
    
    	public static void main(String[] args) {
    
            int[] s={1,2,3,4};
        
            System.out.println("main hashCode: "+s.hashCode());
    
            System.out.println("main ff hashCode: "+ff(s).hashCode());
    
            for(int i:s){
                System.out.println(i);
            }
    }
    main hashCode: 366712642  //数组传递前后,修改前后都没有变化
    ff hashCode: 366712642  
    main ff hashCode: 366712642 
    100                
    2
    3
    4
    

    String(对象、不可变)

    JavaString是对象类型,但也是不可变的,修改也是重新赋值,句柄指向新的字面量。

    public static String ss(String s){
            System.out.println("ss1: "+s.hashCode());
            s+="nice";
            System.out.println("ss2: "+s.hashCode());
            return s;
    
        }
    
    
        public static void main(String[] args) {
    
            String s="Hello Java";
    
            System.out.println("main1: "+s.hashCode());
    
            
            System.out.println("main2: "+ss(s).hashCode());
            System.out.println(s);
    
        }
    main1: 387417328   //传递前后没有变化
    ss1: 387417328
    ss2: 85926989       //修改后hashCode不一样了
    main2: 85926989
    Hello Java
    

    4、GO

    Go语言和C一样,是传值的,就是把实参拷贝一份给形参,不管你是值类型还是引用类型。

    Go语言不同于PythonJava,因为它提供了指针,可以通过传递指针,达到上面那些语言的功能。

    Go中就通过指针模拟面向对象的this关键字

    String(值类型)

    Go中的String是值类型,

    //值类型是拷贝
    func f(data string){
    	fmt.Printf("data:  %p
    ",&data)
    	data+="hi"
    }
    
    func main()  {
    	var s string="ok"
    	fmt.Printf("s    :  %p
    ",&s)
    	f(s)
    
    	fmt.Println("s    :  "+s)
    }
    
    
    s    :  0xc0000421f0  
    data:  0xc000042200  //地址不一样,拷贝了一份新的
    s    :  ok          
    

    []string切片

    func a(data []string)  {
    
    	fmt.Printf("data1:  %p
    ",&data)
    	adata:=append(data,"!")      //生成了新切片,从append函数也可以看出是拷贝了,否则没必要返回一个新切片
        							//func append(slice []Type, elems ...Type) []Type
    	fmt.Printf("data2:  %p,%s
    ",&data,data)
    	fmt.Printf("adata:  %p,%s
    ",&adata,adata)
    
    }
    
    func main()  {
    	var scl []string=[]string{"Hi ","My ","Friend "}
    	fmt.Printf("scl:  %p
    ",&scl)
    	a(scl)  //把实参拷贝一份给形参,互不影响
    
    	fmt.Println(scl) 
    
    }
    
    scl:  0xc000004480
    data1:  0xc0000044c0     //拷贝到新的内存里      
    data2:  0xc0000044c0,[Hi  My  Friend ]
    adata:  0xc0000044e0,[Hi  My  Friend  !] 
    [Hi  My  Friend ]    
    

    []string(切片指针)

    把地址作值传进去,这时形参修改也会影响到实参了。

    Go中模拟面向对象时,用这个特性模拟this关键字。

    func a(data *[]string)  { 
    
    	fmt.Printf("data1:  %p
    ",data)
    	if len(*data)>=0{
    		(*data)[0]="nono"   //这里修改就会影响到外界
    	}
    
    }
    
    func main()  {
    	var scl *[]string=&[]string{"Hi ","My ","Friend "}
    	fmt.Printf("scl:  %p
    ",scl)
    	a(scl)
    
    	fmt.Println(scl)
    
    }
    
    
    scl:  0xc000068440     //地址相同
    data1:  0xc000068440
    &[nono My  Friend ]    //函数影响到了外界
    
  • 相关阅读:
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车按键启动和蜂鸣器报警
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车指定花式动作
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车指定花式动作
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车指定花式动作
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车前后左右综合实验
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车前后左右综合实验
    ZYAR20A 亚克力2驱 蓝牙 298寻迹避障机器人 —— 小车前后左右综合实验
    asp中设置session过期时间方法总结
    asp中设置session过期时间方法总结
    ASP.NET关于Session_End触发与否的问题
  • 原文地址:https://www.cnblogs.com/cgl-dong/p/14060762.html
Copyright © 2011-2022 走看看