http://www.cnblogs.com/dc10101/archive/2009/03/06/1404586.html
unsafe
{
int[] array = new int[10];
for (int i = 0; i < array.Length; i++)
{
array[i] = i;
}
fixed (int* p = array)
{
for (int i = 0; i < array.Length; i++)
{
System.Console.WriteLine(p[i]);
}
}
}
指針在c#中是不提倡使用的,有關指針的操作被認為是不安全的(unsafe)。因此運行這段代碼之前,先要改一個地方,否則編譯不過無法運行。
修改方法:在右側的solution Explorer中找到你的項目,在項目圖標(綠色)上點右鍵,選最後一項properties,然後在Build標簽頁裡把Allow unsafe code勾選上。之後這段代碼就可以運行了,你會看到,上面這段代碼可以像C語言那樣用指針操縱數組。但前提是必須有fixed (int* p = array),它的意思是讓p固定指向數組array,不允許改動。因為C#的自動垃圾回收機制會允許已經分配的內存在運行時進行位置調整,如果那樣,p可能一開始指的是array,但後來array的位置被調整到別的位置後,p指向的就不是array了。所以要加一個fixed關鍵字,把它定在那裡一動不動,之後的操作才有保障。
另有兩點需要注意:
1)指針的使用必須放在unsafe的區域裡;unsafe關鍵字也可作為類或方法的修飾符。
2)fixed (int* p = array)中,p的定義不能寫在別處,而且fixed關鍵字也只能在unsafe區域裡使用。
(*) 略簡潔的unsafe寫法
class Program
{
unsafe public static UInt16 Htons(UInt16 src)
{
UInt16 dest;
// 不能照搬C的源代码,因为有些类型长度不一样,如char(2字节),long(8字节)
// ((char*)&dest)[0] = ((char*)&src)[1];
// ((char*)&dest)[1] = ((char*)&src)[0];
((byte*)&dest)[0] = ((byte*)&src)[1];
((byte*)&dest)[1] = ((byte*)&src)[0];
return dest;
}
public static UInt16 ConciseHtons(UInt16 src)
{
UInt16 dest;
unsafe
{
((byte*)&dest)[0] = ((byte*)&src)[1];
((byte*)&dest)[1] = ((byte*)&src)[0];
}
return dest;
}
static void Main()
{
UInt16 val = 1;
// 如果方法是unsafe的,则必须在unsafe block里调用
unsafe
{
val = Htons(val);
}
Console.WriteLine(val);
// 更简洁的写法是把unsafe block写在函数内部
val = ConciseHtons(val);
Console.WriteLine(val);
}
}
(*) stackalloc
stackalloc的用處僅僅是把數組分配在棧上(默認是分配在托管堆上的)。
class MyClass
{
public int val;
}
class Program
{
static void Main()
{
unsafe
{
MyClass *p = stackalloc MyClass[1]; // Error!! 如果类型要放在托管堆上则不行,如果MyClass是struct就OK了
p->val = 1;
int *iArray = stackalloc int[100]; // OK,在栈上创建数组, int类型本身就是放在栈上的
}
}
}
注意:指針指向的內存一定要固定。凡是C#裡的引用類型(一切類型的數組都是引用類型)都是分配在托管堆上的,都不固定。有兩種方法強制固定,一種是用stackalloc分配在棧上,另一種是用fixed分配在堆上。