C#中指針使用總結

C#中指針使用總結html

C#爲了類型安全,默認並不支持指針。可是也並非說C#不支持指針,咱們能夠使用unsafe關鍵詞,開啓不安全代碼(unsafe code)開發模式。在不安全模式下,咱們能夠直接操做內存,這樣就能夠使用指針了。在不安全模式下,CLR並不檢測unsafe代碼的安全,而是直接執行代碼。unsafe代碼的安全須要開發人員自行檢測。c++

1、Vs2010中開啓unsafe code 的方式c#

在方法、類、代碼塊中使用unsafe關鍵詞,如:api

unsafe static void Main(string[] args){ //代碼}

unsafe { //代碼塊
}


而後再項目上點擊鼠標右鍵,選擇「屬性」,在「生成」選項卡中選中「容許不安全代碼」數組

2、C#能夠定義爲指針的類型有

sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool,
struct(結構體),結構體中只能包括非託管類型。
安全

3、C#指針操做符

操做符 說明
* 取值運算符

 

 

& 取址運算符
-> 經過指針處理結構體中的數據(獲取或賦值)
++與– 指針增、減操做
fixed 用戶暫時固定託管代碼中引用類型的位置。
Stackallc 分配內存

例如分配內存函數

複製代碼
複製代碼
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])); }
複製代碼
複製代碼

至於釋放內存,我在msdn上搜索了一下,c#並無提供釋放內存的函數。而msdn給的解釋是:分配的內存會在方法結束後自動釋放。
fixed的應用會在下面的類與指針中作說明。post

4、C#指針的定義

定義指針 說明
int* p 整形指針
int** p 指向整形指針的指針
char* c 指向字符的指針
int*[] arr 整形一維數組指針

5、指針的使用學習

1.整形指針的使用ui

int i=10; int* iptr = &i;    //將i的地址賦值給iptr
Console.WriteLine((int)&iptr);  //取iptr得地址
Console.WriteLine(*iptr);     //取iptr指向的值

2.結構體指針

複製代碼
複製代碼
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)); }
複製代碼
複製代碼

以上代碼輸出結構體的地址和值。咱們在操做地址時,能夠直接看到結構體的內存分配。

 

3.指針與參數

複製代碼
複製代碼
public static unsafe int* Add(int* x,int* y) { int sum = *x + *y; return &sum; } int i = 2, j = 3; Console.WriteLine(*Add(&i,&j));
複製代碼
複製代碼

4.類與指針,由於類是託管類型,咱們知道類受到「垃圾收集」的影響,它的內存地址是不固定的。並且類是引用類型,是不能聲明爲指針類型的。而指針分配內存後,不受「垃圾收集」影響,地址是固定的。因此爲了使用類中的數據,咱們須要臨時固定類的地址。這就用到fixed關鍵詞,用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
複製代碼
複製代碼

經過以上的方法,咱們能夠操做值類型,也能夠得到值類型的地址。但如何獲取類的內存地址?咱們能夠使用GCHandle,來自System.Runtime.InteropServices命名空間。GCHandle提供從非託管內存訪問託管對象的方法。以下:

object p = new People(); GCHandle h = GCHandle.Alloc(p, GCHandleType.Pinned); IntPtr addr = h.AddrOfPinnedObject(); Console.WriteLine(addr.ToString()); h.Free();

6、C#中使用指針的總結

1.引用類型不能定義爲指針
2.msdn上說enum能夠定義爲指針,但是我真不知道它的用處是什麼。因此在指針的類型中並無出現enum類型。
3.c#中的指針操做遠遠不如c/c++,若是想學習指針的話,仍是用c/c++
4.微軟並不推薦使用unsafe code模式,也不推薦使用指針。在msdn官方文檔中,惟一一句讚美C#指針的話就是「合理的使用指針,能夠提升程序的執行速度」。可是什麼是「合理的使用」?我下載了msdn上的幾個關於C#指針的實例代碼,發現用的最多的是調用api函數,在api函數中,有大量的指針參數。
5.fixed的使用可能產生存儲碎片,由於它們不能移動。若是確實須要固定對象,固定對象的時間應該越短越好。
6.能夠使咱們瞭解非託管類型的內存分配。

分類:  C#
相關文章
相關標籤/搜索