最近在做將Fortran語言移植到C#.net中的工作,由於Fortran是一個用來科學計算的語言,其中大量使用了數組且其操作絕大多數都是對數組的讀寫操作。而熟悉.net框架的人都知道,當我們訪問數組中的元素時,CLR會先檢查索引是否超出了數組的上下界,若超出了,則會拋出System.IndexOutOfRangeException異常。而正是由於這層“保姆程序”,使得.NET程序中對數組操作時無可避免地會有一些性能方面的代價。我們今天要做的事情就是直接跳過這層“保姆程序”,使用指針直接對數組中的元素進行操作。
為了在程序中使用指針,我們需要標示非安全代碼,需要使用特殊的關鍵字unsafe。
非安全代碼是一種介於托管代碼和非托管代碼之間的一種代碼類型,它能像托管代碼一樣在CLR的管理下執行,又能像非托管代碼一樣允許你使用指針直接操作內存。具體來說,凡是使用了*、&、->這些C語言中常用到的任一指針操作符的語句、語句塊或函數都稱為非安全代碼。
實例如下:
unsafe void SquarePtrParam(int* p)
{
*p *= *p;
}
由於CLR管理下的代碼中存在內存重定位的問題,所以為了避免內存洩露,我們需要在語句塊前輸入關鍵字fixed(其功能就是禁止垃圾回收器重定位可移動的變量),告訴CLR該語句塊中的對象或變量不能重定位。
具體的實現過程如下:
在開發環境中設置編譯器選項:打開項目的“屬性”頁——>單擊“生成”頁——>選中“允許不安全代碼”復選框
可行實例代碼如下:
public class QuikeArrayRead
{
unsafe void SquarePtrParam(int* p)
{
*p *= *p;
}
public unsafe void run()
{
int[] arr = new int[] { 1, 2, 3, 4, 5 };
fixed (int* p = &arr[0])
{
for (int i = 0, n = arr.Length; i < n; i++)
{
SquarePtrParam(p+i);
Console.WriteLine(p[i]);
}
}
}
}