|
C#為了類型安全,默認(rèn)并不支持指針。但是也并不是說C#不支持指針,我們可以使用unsafe關(guān)鍵詞,開啟不安全代碼(unsafe code)開發(fā)模式。在不安全模式下,我們可以直接操作內(nèi)存,這樣就可以使用指針了。在不安全模式下,CLR并不檢測unsafe代碼的安全,而是直接執(zhí)行代碼。unsafe代碼的安全需要開發(fā)人員自行檢測。 一、Vs2010中開啟unsafe code 的方式 在方法、類、代碼塊中使用unsafe關(guān)鍵詞,如: unsafe static void Main(string[] args){ //代碼} unsafe { //代碼塊 }
二、C#可以定義為指針的類型有sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool, 三、C#指針操作符
例如分配內(nèi)存 char* cptr = stackalloc char[26]; for (int i = 0; i < 26;i++ ) { cptr[i] = (char) (i+65); } for (int i = 0; i < 26;i++ ) { Console.WriteLine(string.Format("{0}:{1}",(int)&cptr[i],cptr[i])); } 至于釋放內(nèi)存,我在msdn上搜索了一下,c#并沒有提供釋放內(nèi)存的函數(shù)。而msdn給的解釋是:分配的內(nèi)存會在方法結(jié)束后自動(dòng)釋放。 四、C#指針的定義
五、指針的使用 1.整形指針的使用 int i=10; int* iptr = &i; //將i的地址賦值給iptr Console.WriteLine((int)&iptr); //取iptr得地址 Console.WriteLine(*iptr); //取iptr指向的值 2.結(jié)構(gòu)體指針 struct Location { public int X; public int Y; } unsafe static void Main(string[] args) { Location location; location.X = 10; location.Y = 5; Location* lptr = &location; Console.WriteLine(string.Format("location 地址{0},lptr地址{1},lptr值{2}",(int)&location,(int)lptr,*lptr)); Console.WriteLine(string.Format("location.x的地址{0},location.x的值{1}",(int)&(lptr->X),lptr->X)); Console.WriteLine(string.Format("location.y的地址{0},location.y的值{1}", (int)&(lptr->Y), lptr->Y)); } 以上代碼輸出結(jié)構(gòu)體的地址和值。我們在操作地址時(shí),可以直接看到結(jié)構(gòu)體的內(nèi)存分配。
3.指針與參數(shù) public static unsafe int* Add(int* x,int* y) { int sum = *x + *y; return ∑ } int i = 2, j = 3; Console.WriteLine(*Add(&i,&j)); 4.類與指針,因?yàn)轭愂峭泄茴愋停覀冎李愂艿健袄占钡挠绊?,它的?nèi)存地址是不固定的。而且類是引用類型,是不能聲明為指針類型的。而指針分配內(nèi)存后,不受“垃圾收集”影響,地址是固定的。所以為了使用類中的數(shù)據(jù),我們需要臨時(shí)固定類的地址。這就用到fixed關(guān)鍵詞,用fixed后,就可以操作類中的值類型了。 class People { public int Age; //值類型,不可以是屬性 public void ShowAge() { Console.WriteLine(Age); } } People people = new People(); people.Age = 10; fixed(int* agePtr=&people.Age) { *agePtr += 1; } people.ShowAge(); //11 通過以上的方法,我們可以操作值類型,也可以獲得值類型的地址。但如何獲取類的內(nèi)存地址?我們可以使用GCHandle,來自System.Runtime.InteropServices命名空間。GCHandle提供從非托管內(nèi)存訪問托管對象的方法。如下: object p = new People(); GCHandle h = GCHandle.Alloc(p, GCHandleType.Pinned); IntPtr addr = h.AddrOfPinnedObject(); Console.WriteLine(addr.ToString()); h.Free(); 六、C#中使用指針的總結(jié)1.引用類型不能定義為指針 |
|
|