【问题标题】:When i change the value of an multidimensional array, the value at the same position of another array changes too. Why?当我改变一个多维数组的值时,另一个数组相同位置的值也会改变。为什么?
【发布时间】:2014-10-25 08:34:33
【问题描述】:

我花了很多时间才弄清楚这一点。

我有 2 个多维数组:

int[,] OldGeneration = new int[WidthX + 1, HeightY + 1];
int[,] NextGeneration = new int[WidthX + 1, HeightY + 1];

稍后在我的代码中,在“NextGeneration”中设置一些值后,我使数组包含相同的值。

OldGeneration = NextGeneration;

当我在运行程序时检查值时,它的工作原理。

然后我更改“NextGeneration”的一个值,当我这样做时,“OldGeneration”中的相同值也将被更改。

你能告诉我为什么吗?

using System;

namespace CGoL
{
    class CGoL_Base
    {
        static void Main(string[] args)
        {
            //Declare and define (initialize) Variables used by the Program
            int WidthX = 5, HeightY = 5, Iterations = 5, Speed = 1000, Random = 0, CellsAlive = 0;

            //Declare Multidimensional Arrays for actual generation and next generation
            int[,] OldGeneration = new int[WidthX + 1, HeightY + 1];
            int[,] NextGeneration = new int[WidthX + 1, HeightY + 1];


            //###########   Initialize "Game Board"   ##########################

            //Set Game Board to contain only dead cells
            for (int y = 1; y <= HeightY; y++)
            {
                for (int x = 1; x <= WidthX; x++)
                {
                    NextGeneration[x, y] = 0;
                }
            }

            //Set pattern for oscillating (moving) structure with 3 living cells (Can be changed at will)
            NextGeneration[3, 2] = 1;
            NextGeneration[3, 3] = 1;
            NextGeneration[3, 4] = 1;

            //Set OldGeneration equal with NextGeneration so that the calculation can work
            OldGeneration = NextGeneration;

            //##################################################################

            //Start the iterationcounter
            for (int Iteration = 1; Iteration <= Iterations; Iteration++)
            {
                //###########   Calculate actual generation   ######################
                //Calculate how the Game Board will change with the usual CGoL rules

                if (Iteration >= 2) //Without this, the initialization above will not work
                {
                    for (int y = 1; y <= HeightY; y++)
                    {
                        for (int x = 1; x <= WidthX; x++)
                        {
                            //###########   Check surrounding Cells   ##########################
                            //Check how much cells, surrounding the actual cell, are still alive
                            //to calculate later how the Game Board will change

                            CellsAlive = 0;

                            for (int i = -1; i <= 1; i++)
                            {
                                for (int n = -1; n <= 1; n++)
                                {

                                    if (i == 0 && n == 0)
                                    {
                                        continue;
                                    }

                                    //Check if some Array Index will be out of Array Range (for example when index is smaller than 0)
                                    if (x + n == 0 || x + n > WidthX || y + i == 0 || y + i > HeightY)
                                    {
                                        continue;
                                    }
                                    if (OldGeneration[(x + n), (y + i)] == 1)
                                    {
                                        CellsAlive++;
                                    }
                                }
                            }

                            //##################################################################

                            //If a dead cell got 3 living neighbours, the cell will become alive in the next generation
                            if (OldGeneration[x, y] == 0 && CellsAlive == 3)
                            {
                                NextGeneration[x, y] = 1;
                            }
                            //If a living cell got less than 2 living neighbours, the cell will die in the next generation
                            else if (OldGeneration[x, y] == 1 && CellsAlive < 2)
                            {
                                NextGeneration[x, y] = 0; //OldGeneration[x, y] will be changed to 0 even if it is not written here????? why?
                            }
                            //If a living cell got 2 or 3 living neighbours, the cell will stay alive in the next generation
                            else if (OldGeneration[x, y] == 1 && (CellsAlive == 2 || CellsAlive == 3))
                            {
                                NextGeneration[x, y] = 1;
                            }
                            //If a living cell got more than 3 living neighbours, the cell will die in the next generation
                            else if (OldGeneration[x, y] == 1 && CellsAlive > 3)
                            {
                                NextGeneration[x, y] = 0;
                            }
                        }
                    }
                    Console.ReadKey();
                }

                //##################################################################

                //###########   Draw the "Game Board"   ############################

                //Makes the console window Empty :)

                Console.Clear();

                //"for" is making new rows with Console.Write("\n");
                for (int y = 1; y <= HeightY; y++)
                {
                    //"for" is writing "O"'s in one row
                    for (int x = 1; x <= WidthX; x++)
                    {
                        if (NextGeneration[x, y] == 1)
                        {
                            Console.Write("O ");
                        }
                        else
                        {
                            Console.Write("  ");
                        }
                    }
                    Console.Write("\n");
                }

                Console.WriteLine("Iteration: {0}", Iteration);

                System.Threading.Thread.Sleep(Speed);

                //At the end, make the actual generation same like the old generation to be calculated next
                OldGeneration = NextGeneration;

                //##################################################################
            }

            Console.ReadKey();
        }
    }
}

【问题讨论】:

    标签: c# arrays multidimensional-array conways-game-of-life


    【解决方案1】:

    当您声明时:

    OldGeneration = NextGeneration;
    

    您正在将 NextGeneration 的引用分配给 OldGeneration,因此您对其中一个所做的任何更改也会反映到另一个是正常的。

    如果你想制作一个不相交的副本,你应该使用Array.Copyhttp://msdn.microsoft.com/it-it/library/y5s0whfd(v=vs.110).aspx

    【讨论】:

      【解决方案2】:

      这行是问题所在:OldGeneration = NextGeneration;

      在这一行之前你有两个对象(两个数组),在它之后你有一个对象,两个变量都在看。您必须在双循环中复制内容,而不是上面的行。

      【讨论】:

        【解决方案3】:

        这是因为您没有让数组包含相同的值,而是将一个数组的引用替换为对另一个数组的引用。

        从那时起,两个变量都引用同一个数组。当您使用一个变量更改数组时,当您使用另一个变量查看数组时,更改将可见,因为它是同一个数组。

        如果要将数据从一个数组复制到另一个数组,可以使用Array.Copy method

        Array.Copy(NextGeneration, OldGeneration, NextGeneration.Length);
        

        【讨论】:

        • 非常感谢。这对我有用。通常我在 Perl 中使用哈希,并且正在努力使它们“相同”。谢谢
        【解决方案4】:

        使用这条线:

        OldGeneration = NextGeneration;
        

        您使OldGeneration 变量引用与NextGeneration 变量相同的内存。

        您可以改为复制数组:

        Array.Copy(NextGeneration, OldGeneration, NextGeneration.Length);
        

        【讨论】:

        • 这不起作用。然后它告诉它它只适用于一维数组。
        猜你喜欢
        • 2011-05-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-20
        • 1970-01-01
        • 1970-01-01
        • 2020-06-17
        • 1970-01-01
        相关资源
        最近更新 更多