C#指標型別
操作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 );
}
}
在不安全的上下文中,型別可以是指標型別以及值型別或引用型別。指標型別宣告具有下列形式之一:
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 語句 |
臨時固定變數以便可以找到其地址。 |
相關文章
- go 方法接受者 是指標型別和非指標型別的 區別Go指標型別
- c指標型別的作用指標型別
- 常見指標型別入門指標型別
- 第 10 節:複合型別-5. 指標 -- 指標與指標變數 -8. 多級指標型別指標變數
- golang中 值型別,指標,引用的區別Golang型別指標
- golang 指標型別引起的神奇 bugGolang指標型別
- 第十五章:指標型別指標型別
- sizeof和strlen計算陣列型別和指標型別字串陣列型別指標字串
- Golang研學:在用好Golang指標型別Golang指標型別
- C#中使用指標C#指標
- Unreal 各種指標型別是怎麼回事Unreal指標型別
- 認真一點學 Go:14. 指標型別Go指標型別
- C# 指標複習示例C#指標
- c#:值型別&引用型別C#型別
- C#的型別——值型別與引用型別C#型別
- 第六章 指標和型別限定符指標型別
- Go語言高階資料型別之指標篇Go資料型別指標
- 指標問題的一點體會(區別 [指向指標的指標] 與 [指標的指標] .) (轉)指標
- All I know about A/B Test (1) : 均值型指標與比值(率)型指標的計算區別指標
- 指標常量和常量指標的區別指標
- 不同型別的指標型別指標
- [C#]強型別C#型別
- 【C#之值型別vs引用型別】C#型別
- c#中值型別和引用型別的區別C#型別
- 【C#學習筆記】指標使用C#筆記指標
- C#中的函式指標 (轉)C#函式指標
- C#變數型別(1):引用型別和值型別 (轉)變數型別
- C# 物件比較(值型別、引用型別)C#物件型別
- 型別與泛型標記型別泛型
- 指標和引用的區別指標
- 當char型變數遇上char*型的指標變數指標
- C#型別詳解C#型別
- C# 型別轉換C#型別
- NULL 指標、零指標、野指標Null指標
- GraphQL —— 標量型別型別
- Golang 學習——陣列指標和指標陣列的區別Golang陣列指標
- C# 泛型 引用型別約束 值型別約束C#泛型型別
- C# 9.0 新特性之目標型別推導 new 表示式C#型別