按值和按引用传递数组 [英] Passing Arrays by Value and by Reference

查看:36
本文介绍了按值和按引用传递数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这些是我正在阅读的一本 c# 书中的例子,只是在理解这个例子实际上在做什么时有点困难,希望得到一个解释,以帮助我进一步了解这里发生的事情.

//创建并初始化firstArrayint[] firstArray = { 1, 2, 3 };//复制变量firstArray中的引用并赋值给firstarraycopyint[] firstArrayCopy = firstArray;Console.WriteLine("测试通过值传递 firstArray 引用");Console.Write("\nfirstArray 的内容 " +"在调用 FirstDouble 之前:\n\t");//使用计数器用forloop显示firstArray的内容for (int i = 0; i < firstArray.Length; i++)Console.Write("{0} ", firstArray[i]);//将变量firstArray按值传递给FirstDoubleFirstDouble(firstArray);Console.Write("\n\n" + 之后 firstArray 的内容"调用 FirstDouble\n\t");//显示firstArray的内容for (int i = 0; i < firstArray.Length; i++)Console.Write("{0} ", firstArray[i]);//测试引用是否被 FirstDouble 改变if (firstArray == firstArrayCopy)Console.WriteLine("\n\n引用指向同一个数组");别的Console.WriteLine("\n\n引用指向不同的数组");//带参数数组的firstdouble方法public static void FirstDouble(int[] array){//将每个元素值加倍for (int i = 0; i 

基本上有代码我想知道的是,这本书说如果数组是按值传递的,而不是原始调用者没有被方法修改(根据我的理解).因此,在方法 FirstDouble 结束时,他们尝试将局部变量数组分配给一组失败的新元素,并且显示时原始调用者的新值是 2,4,6.

现在我的困惑是方法 FirstDouble 中的 for 循环如何将原始调用者 firstArray 修改为 2,4,6,如果它是按值传递的.我认为该值应保持为 1、2、3.

提前致谢

解决方案

理解这一点的关键是要了解 值类型和引用类型.

例如,考虑一个典型的值类型,int.

int a = 1;int b = a;一个++;

执行此代码后,a 的值为 2,b 的值为 1.因为 int 是值类型,所以 b = a 获取 a 的值的副本.

现在考虑一个类:

MyClass a = new MyClass();a.MyProperty = 1;我的类 b = a;a.MyProperty = 2;

因为类是引用类型,b = a 只分配引用而不是值.所以 ba 都指向同一个对象.因此,在 a.MyProperty = 2 执行后, b.MyProperty == 2 因为 ab 指的是同一个对象.

<小时>

考虑到您问题中的代码,数组是引用类型,因此对于此函数:

public static void FirstDouble(int[] array)

变量array实际上是一个引用,因为int[]是一个引用类型.所以array 是一个引用,它是传值.

因此,在函数内部对array 所做的修改实际上应用于array 引用的int[] 对象.所以这些修改对所有引用同一个对象的引用都是可见的.这包括调用者持有的引用.

现在,如果我们看一下这个函数的实现:

public static void FirstDouble(int[] array){//将每个元素值加倍for (int i = 0; i 

还有一个更复杂的问题.for 循环只是将传递给函数的 int[] 的每个元素加倍.这就是调用者看到的修改.第二部分是将一个新的int[] 对象赋值给局部变量array.这对调用者是不可见的,因为它所做的只是改变引用array 的目标.并且由于引用 array 是按值传递的,调用者看不到那个新对象.

如果函数是这样声明的:

public static void FirstDouble(ref int[] array)

然后引用 array 将通过引用传递,调用者将在函数返回时看到新创建的对象 { 11, 12, 13 }.>

These are example from a c# book that I am reading just having a little trouble grasping what this example is actually doing would like an explanation to help me further understand what is happening here.

        //creates and initialzes firstArray
        int[] firstArray = { 1, 2, 3 };

        //Copy the reference in variable firstArray and assign it to firstarraycopy
        int[] firstArrayCopy = firstArray;

        Console.WriteLine("Test passing firstArray reference by value");


        Console.Write("\nContents of firstArray " +
            "Before calling FirstDouble:\n\t");

        //display contents of firstArray with forloop using counter
        for (int i = 0; i < firstArray.Length; i++)
            Console.Write("{0} ", firstArray[i]);

        //pass variable firstArray by value to FirstDouble
        FirstDouble(firstArray);

        Console.Write("\n\nContents of firstArray after " +
            "calling FirstDouble\n\t");

        //display contents of firstArray
        for (int i = 0; i < firstArray.Length; i++)
            Console.Write("{0} ", firstArray[i]); 

        // test whether reference was changed by FirstDouble
        if (firstArray == firstArrayCopy)
            Console.WriteLine(
                "\n\nThe references refer to the same array");
        else
            Console.WriteLine(
                "\n\nThe references refer to different arrays");

       //method firstdouble with a parameter array
       public static void FirstDouble(int[] array)
    {
        //double each elements value
        for (int i = 0; i < array.Length; i++)
            array[i] *= 2;

        //create new object and assign its reference to array
        array = new int[] { 11, 12, 13 };

Basically there is the code what I would like to know is that the book is saying if the array is passed by value than the original caller does not get modified by the method(from what i understand). So towards the end of method FirstDouble they try and assign local variable array to a new set of elements which fails and the new values of the original caller when displayed are 2,4,6.

Now my confusion is how did the for loop in method FirstDouble modify the original caller firstArray to 2,4,6 if it was passed by value. I thought the value should remain 1,2,3.

Thanks in advance

解决方案

The key to understanding this is to know the difference between a value type and a reference type.

For example, consider a typical value type, int.

int a = 1;
int b = a;
a++;

After this code has executed, a has the value 2, and b has the value 1. Because int is a value type, b = a takes a copy of the value of a.

Now consider a class:

MyClass a = new MyClass();
a.MyProperty = 1;
MyClass b = a;
a.MyProperty = 2;

Because classes are reference types, b = a merely assigns the reference rather than the value. So b and a both refer to the same object. Hence, after a.MyProperty = 2 executes, b.MyProperty == 2 since a and b refer to the same object.


Considering the code in your question, an array is a reference type and so for this function:

public static void FirstDouble(int[] array)

the variable array is actually a reference, because int[] is a reference type. So array is a reference that is passed by value.

Thus, modifications made to array inside the function are actually applied to the int[] object to which array refers. And so those modifications are visible to all references that refer to that same object. And that includes the reference that the caller holds.

Now, if we look at the implementation of this function:

public static void FirstDouble(int[] array)
{
    //double each elements value
    for (int i = 0; i < array.Length; i++)
        array[i] *= 2;

    //create new object and assign its reference to array
    array = new int[] { 11, 12, 13 };
}

there is one further complication. The for loop simply doubles each element of the int[] that is passed to the function. That's the modification that the caller sees. The second part is the assignment of a new int[] object to the local variable array. This is not visible to the caller because all it does is to change the target of the reference array. And since the reference array is passed by value, the caller does not see that new object.

If the function had been declared like this:

public static void FirstDouble(ref int[] array)

then the reference array would have been passed by reference and the caller would see the newly created object { 11, 12, 13 } when the function returned.

这篇关于按值和按引用传递数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆