从内存变化看.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里面去运行,用自己脑子想想,以上代码运行结果是什么?![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
18
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
第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
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
18
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
现在运行结果是什么?注意别动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
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
2
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
3
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
4
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
5
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
9
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
10
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
11
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
12
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
16
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
18
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
现在的运行结果是什么?
从内存的角度来看,程序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拿掉测试一下,加深理解!