C#指標型別

c_link發表於2011-02-27

操作c#中的指標,是一種編寫非託管中的一種技術。
c#中指標型別可能是(儲存在棧)中的值型別,也可能是(儲存在堆)中的引用
型別。不過無論是什麼型別,基本格式都有一個共同的要求就是必須都是支援非
託管的型別或者空型別。
(這裡順便提一句,非託管的型別編譯依賴系統型別庫,而託管的型別依賴CLR中元
資料.)
在C#中支援非託管的型別包括: sbyte, byte, short, ushort, int, uint,
long, ulong, char, float, double, decimal , bool ,enum ,pointer,void和
使用者自定義的結構體型別(但需要注意這裡結構體元素必須也是支援非託管的)
定義指標型別格式:
非託管型別* 名稱;
例如:int* p;
這裡需要注意指標型別是一種型別,宣告和一般原C#託管型別一樣.
所以可以支援int* p ,q,不支援int* p,*q表示方法.
1,指標型別做陣列操作
C#非託管型別可以像C++一樣在非託管堆上分配地址,使用stackalloc操作.
並且通過和C++一樣的操作方式*用於取地址實際內容或者[]索引方式訪問.
例如:
static unsafe void Main()
{
//分配p1一個100的大小
int* p1 = stackalloc int[100];
//賦值操作
for (int i = 0; i < 100; i++)
{
p1[i] = i;
}
//測試內容
for (int i = 0; i < 100; i++)
{
         Console.WriteLine(p1[i]);
Console.WriteLine(*(p1+i));
        }
}
注意,這裡Main函式需要宣告是unsafe(非託管的程式碼)
2,用於獲得物件地址
static unsafe void Main()
{
int i = 10; //宣告一個int的存放地址
int* p = &i;//獲得i存放的記憶體地址
Console.WriteLine(*p);//測試
}
除了上面提到的內容外,C#指標型別可以完成幾乎所有C++指標可以實現的操作.
參考資料:
Pointer types (MSDN C# Programming Guide)

一個例子,在.NET Framework SDK Documentation中
using System;
struct Point
{
public int x, y;
}

class Test
{
public static void Main()
{
Point pt = new Point();
unsafe
{
Point* pp = &pt;
pp->x = 123;
pp->y = 456;
}

Console.WriteLine ( "{0} {1}", pt.x, pt.y );
}
}

指標型別(C# 程式設計指南)

 

在不安全的上下文中,型別可以是指標型別以及值型別或引用型別。指標型別宣告具有下列形式之一:

unmanaged type* identifier;
void* identifier;

引數

unmanaged type

下列軟體之一:

  • sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal 或 bool。

  • 任何列舉型別。

  • 任何指標型別。

  • 僅包含非託管型別的欄位的任何使用者定義的結構型別。

identifier

指標變數名稱

指標型別不繼承 object,並且指標型別與 object 之間不存在轉換。此外,裝箱和取消裝箱不支援指標。但是,允許在不同指標型別之間以及指標型別與整型之間進行轉換。

當在同一個宣告中宣告多個指標時,* 僅與基礎型別一起使用,而不是作為每個指標名稱的字首。例如:

int* p1, p2, p3;   // Ok
int *p1, *p2, *p3; // Invalid in C#

指標不能指向引用或包含引用的結構,因為垃圾回收器不知道關於指標的任何資訊,但知道關於引用的資訊。

myType* 型別的指標變數的值是 myType 型別的變數的地址。下面是指標型別宣告的示例:

示例 說明

int* p

p 是指向整數的指標

int** p

p 是指向整數的指標的指標

int*[] p

p 是指向整數的指標的一維陣列

char* p

p 是指向字元的指標

void* p

p 是指向未知型別的指標

指標間接定址運算子 * 可用於訪問位於指標變數所指向的位置的內容。例如,對於下面的宣告,

int* myVariable;

表示式 *myVariable 表示在 myVariable 中包含的地址處找到的 int 變數。

不能對 void* 型別的指標應用間接定址運算子。但是,可以使用強制轉換將 void 指標轉換為其他指標型別,反之亦然。

指標可以為 null。如果將間接定址運算子應用於 null 指標,則會導致由實現定義的行為。

注意,在方法之間傳遞指標會導致未定義的行為。示例包括通過 Out 或 Ref 引數向區域性變數返回指標或作為函式結果向區域性變數返回指標。如果將指標設定在固定的塊中,它所指向的變數可能不再是固定的。

下表列出可在不安全的上下文中針對指標執行的運算子和語句:

運算子/語句 用途

*

執行指標間接定址。

->

通過指標訪問結構的成員。

[]

對指標建立索引。

&

獲取變數的地址。

++ 和 --

遞增或遞減指標。

加、減

執行指標演算法。

==、!=、<、>、<= 和 >=

比較指標。

stackalloc

在堆疊上分配記憶體。

fixed 語句

臨時固定變數以便可以找到其地址。

相關文章