从内存变化看.NET代码执行机理(四)

 1    class Program
 2    {
 3        public static void text(int x)
 4        {
 5            Console.WriteLine("第5行代码:" + x);
 6            x = x * 2;
 7            Console.WriteLine("第7行代码:" + x);
 8         }

 9        static void Main(string[] args)
10        {
11            int a;
12            a = 5;
13            Console.WriteLine("第13行代码:" + a);
14            text(a);
15            Console.WriteLine("第15行代码:" + a);
16            Console.ReadKey();
17        }

18    }
以上我们定名叫程序a,首先不要马上把代码拷贝到IDE里面去运行,用自己脑子想想,以上代码运行结果是什么?
第13行代码:5
第5行代码:5
第7行代码:10
第15行代码:10
还是
第13行代码:5
第5行代码:5
第7行代码:10
第15行代码:5
你认为是哪个?从内存的变化中来分析是为什么?
好,代码改一下,在上面代码的基础上只加两个ref关键字,程序b
 1    class Program
 2    {
 3        public static void text(ref int x)
 4        {
 5            Console.WriteLine("第5行代码:" + x);
 6            x = x * 2;
 7            Console.WriteLine("第7行代码:" + x);
 8         }

 9        static void Main(string[] args)
10        {
11            int a;
12            a = 5;
13            Console.WriteLine("第13行代码:" + a);
14            text(ref a);
15            Console.WriteLine("第15行代码:" + a);
16            Console.ReadKey();
17        }

18    }

现在运行结果是什么?注意别动IED,用脑子考虑.
再改一下,注意中间变化(程序c)
 1    class Program
 2    {
 3        public static void text(out int x)
 4        {   x = 15;
 5            Console.WriteLine("第5行代码:" + x);
 6            x = x * 2;
 7            Console.WriteLine("第7行代码:" + x);
 8         }

 9        static void Main(string[] args)
10        {
11            int a;
12            a = 5;
13            Console.WriteLine("第13行代码:" + a);
14            text(out a);
15            Console.WriteLine("第15行代码:" + a);
16            Console.ReadKey();
17        }

18    }

现在的运行结果是什么?
从内存的角度来看,程序a很简单.其运行结果为
第13行代码:5
第5行代码:5
第7行代码:10
第15行代码:5
疑点如果有的话,应该是在最后第15行代码的输出上,为什么不是10?因为

x在得到text(a);后自己在栈中申请了一份内存,并把a的内容5复制了一份到自己的内容中,然后做5*2操作,最后X的值为10,而a的值一直是5不变.

程序b的运行结果是
第13行代码:5
第5行代码:5
第7行代码:10
第15行代码:10
看起来变化的是第15行代码的输出,其实从内存里面看,机理和程序a完全不一样(实参地址考入形参)

text(ref a)public static void text(ref int x)表示为传址方式,既x在text(ref a)的时候得到的不是5这个数值,而是存放5的内存地址123456.x从地址123456映射到a中的数值5.如果x做乘2操作,那么系统读取x内存的内容时发现是栈地址123456,将会延着这个地址跟踪操作到a中的数值5.乘2后a中的5变10,x中的地址123456不变.
程序c中的运行结果为
第13行代码:5
第5行代码:15
第7行代码:30
第15行代码:30
其运行机理与程序b正好相反.(形参地址考入实参)
首先申明a在栈中申请一块内存,并赋值5,地址为123456

执行text(out a)--public static void text(out int x)后, x在内存中申请一块内存,同时把x的内存地址考进a的内容中,x的内存内容为空.

然后代码给出定义x=15.x的内存内容刷成15.

后面的计算就简单了,x*2表示从x中15*2=30,表示x最终被刷成30,而a是通过x的内存地址123457指向x的内存内容.所以第7行代码和第15行代码输出都是30.

可以把x=15拿掉测试一下,加深理解!
原文地址:https://www.cnblogs.com/tommyli/p/1349695.html