请看下面的代码:
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Pointer
{
class Program
{
static void Main(string[] args)
{
Int32 i = 0;
Console.WriteLine("Before unsafe code, i = {0}", i);
long l = 0;
unsafe // Seg 1
{
l = (long)&i;
l++;
char* ptr = (char*)l;
*ptr = 'a';
}
Console.WriteLine("After unsafe code seg 1, i = {0}", i);
unsafe // 2
{
char* ptr = (char*)l;
Console.WriteLine("Inside unsafe code seg 2, *ptr = {0}", *ptr);
}
Console.WriteLine("QUESTION: There is no code to modify variable i directly, why the value of i is changed to 24832?");
}
}
}
输出结果是:
Before unsafe code, i = 0
After unsafe code seg 1, i = 24832
Inside unsafe code seg 2, *ptr = a
QUESTION: There is no code to modify variable i directly, why the value of i is
changed to 24832?
请按任意键继续. . .
是不是觉得很难理解啊,这就对了,下面来看看对上面代码的分析:
1、我们看变量"l"它是一个存放&i的变量,只不过它是一个long型的,而int32 i在内存中只是站上4个Byte如下图:
图 1-1
注: l = (long)&i;//如上图把四字节的一个"i"值得罪地位地址转换为long型后赋给long型变量"l",l++=06d4ecd0+1=06d4ecd1(这个值仅仅是一个随机的内存 地址的值)
2、char* ptr = (char*)l;接下来是把"l"强制转换为一个指向char类型的指针然后赋给指针ptr,其实此时ptr是指向(int32 i)的次低位,如下图:
图1-2
3、由于ptr其实是&i 的基础自加一位,所以ptr的指向如图1-2所示,只是此时ptr是指向char型的,此时将'a'赋值给*ptr,效果如图:
图1-3
int32 i,值用十六进制表示就是0x00006100,换成十进制就是上面输出的结果:i=24832