zoukankan      html  css  js  c++  java
  • 结构变量作为方法的参数调用

    结构变量作为方法的参数调用,在方法内部使用的“坑”你遇到过吗?

    很久没有写博了,今天一个同学在问结构变量的问题,问结构到底是传递值还是传递引用。查过MSDN的都知道,结构默认是传递值的,因此在方法内部,结构的值会被复制一份。但是对于结构数组,如果值还是要被复制一份,这个内存占用是不是很多了呢?
    一般来说,数组参数传递的是引用,那么数组的元素呢?它是被复制的还是被引用的?如果结构数组的元素象结构变量那样也是复制的,那么对于方法调用的内存占用问题,就得好好考虑下了。

    MSDN看了半天,也讨论了半天,感觉还是没有动手实验最有说服力,我们先定义一个结构体:

    复制代码
    struct Point
        {
            public int X;
            public int Y;
            public Point(int x, int y)
            {
                this.X = x;
                this.Y = y;
            }
        }
    复制代码

    定义2个方法,分别以传值和传引用的方式来调用结构变量:

    复制代码
            static void TestStruc(Point p)
            {
                p.X++;
                p.Y++;
    
            }
    
            static void TestStruc2(ref Point p)
            {
                p.X++;
                p.Y++;
    
            }
    复制代码

    调用代码:

    复制代码
                Point p = new Point(1, 2);
                TestStruc(p);
                Console.WriteLine("call by value Point X={0},Y={1}", p.X, p.Y);
    
                TestStruc2(ref p);
                Console.WriteLine("call by ref Point X={0},Y={1}", p.X, p.Y);
    复制代码

    调用结果符合预期,以引用传递的结构变量,它的值被改变了:

    Struct Pont(X,Y) Test:
    call by value Point X=1,Y=2
    call by ref Point X=2,Y=3

    下面,试试结构数组,看有何不同:

    复制代码
            static void TestStrucArray2(ref Point[] arr)
            {
                Point p = arr[0];
                p.X++;
                p.Y++;
    
            }
    复制代码

    调用代码:

    复制代码
                Point[] arr = new Point[2];
                arr[0] = new Point(1, 2);
                arr[1] = new Point(3, 4);
    
                TestStrucArray(arr);
                Console.WriteLine("call by value Point[0]: X={0},Y={1}", arr[0].X, arr[0].Y);
    复制代码

    结果:

    call by value Point[0]: X=1,Y=2

    方法内部对结果数组元素的改变无效,难道结构数组被复制了?

    惊出一身冷汗!

    改成引用参数的方式来试试,避免复制结构数组:

    复制代码
           static void TestStrucArray2(ref Point[] arr)
            {
                Point p = arr[0];
                p.X++;
                p.Y++;
    
            }
    复制代码

    结果:

    call by value Point[0]: X=1,Y=2
    call by ref Point[0]: X=1,Y=2

    引用方式数组还是被复制了?看来哪里有问题阿。

    去掉用一个结构变量来引用结构数组的成员,直接操作结构数组的元素,来看看调用结果:

    复制代码
            static void TestStrucArray3( Point[] arr)
            {
                //Point p = arr[0];
                arr[0].X++;
                arr[0].Y++;
    
            }
    
            static void TestStrucArray4(ref Point[] arr)
            {
                arr[0].X++;
                arr[0].Y++;
    
            }
    复制代码

    调用代码:

    复制代码
                TestStrucArray4(ref arr);
                Console.WriteLine("call by ref Point[0] not use var : X={0},Y={1}", arr[0].X, arr[0].Y);
                arr[0].X = 1; arr[0].Y = 2;
    
                TestStrucArray3( arr);
                Console.WriteLine("call by var Point[0] not use var : X={0},Y={1}", arr[0].X, arr[0].Y);
    复制代码

    结果:

    call by ref Point[0] not use var : X=2,Y=3
    call by var Point[0] not use var : X=2,Y=3

    直接操作结构数组的元素,元素的值被改变了,证明结构数组没有复制数组元素的值,依然是对数组的引用,上面的问题虚惊一场。

    我们对比下前后不同的代码,发现TestStrucArray2 仅仅多了一行代码:

    复制代码
           static void TestStrucArray2(ref Point[] arr)
            {
                Point p = arr[0];
                p.X++;
                p.Y++;
    
            }
    复制代码

    这说明,定义一个结构变量,让另外一个结构变量的值赋值给它,等于是复制这个结构变量的值。

    往往有时候,我们为了敲代码方便,少写几个字,便定义一个临时变量去引用原来的变量,而这种行为,对于操作结构变量,无疑是一个最大的坑,这个坑,你遇到过吗?

     
     
    分类: 编程语言
    标签: 结构变量数组
  • 相关阅读:
    乱码解决
    Collection接口
    YTU EDG Vince Day Training -- 训练赛赛后总结
    Codeforces Round #751 (Div. 2) A. Two Subsequences
    Codeforces Round #750 (Div. 2) C. Grandma Capa Knits a Scarf
    Codeforces Round #745 (Div. 2) B. Diameter of Graph
    Codeforces Round #745 (Div. 2) A. CQXYM Count Permutations
    ytuoj-3328 快速幂
    Codeforces Round #746 (Div. 2) C. Bakry and Partitioning
    Codeforces Round #747 (Div. 2) B. Special Numbers
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3205602.html
Copyright © 2011-2022 走看看