C#指針變量與unsafe的實(shí)現(xiàn)
為了保持類型的安全性,默認(rèn)情況下 C# 是不支持指針的,但是如果使用 unsafe 關(guān)鍵字來修飾類或類中的成員,這樣的類或類中成員就會被視為不安全代碼,C# 允許在不安全代碼中使用指針變量。在公共語言運(yùn)行時 (CLR) 中,不安全代碼是指無法驗(yàn)證的代碼,不安全代碼不一定是危險的,只是 CLR 無法驗(yàn)證該代碼的安全性。因此 CLR 僅會執(zhí)行信任程序集中包含的不安全代碼。
指針變量
在 C# 中,指針同樣是一個變量,但是它的值是另一個變量的內(nèi)存地址,在使用指針之前我們同樣需要先聲明指針,聲明指針的語法格式如下所示:
type* var_name;
下表中列舉了一些定義指針的示例:
示例 | 說明 |
---|---|
int* p | p 是指向整數(shù)的指針 |
double* p | p 是指向雙精度數(shù)的指針 |
float* p | p 是指向浮點(diǎn)數(shù)的指針 |
int** p | p 是指向整數(shù)的指針的指針 |
int*[] p | p 是指向整數(shù)的指針的一維數(shù)組 |
char* p | p 是指向字符的指針 |
void* p | p 是指向未知類型的指針 |
與聲明變量相同,我們同樣可以在一行代碼中同時聲明多個指針,如下所示:
int* p1, p2, p3; ?// 定義 p1、p2、p3 三個整數(shù)指針
注意:指針類型不能從對象中繼承,并且裝箱和拆箱也不支持指針,但是不同的指針類型以及指針與整型之間可以進(jìn)行轉(zhuǎn)換。
【示例】下面通過示例演示 C# 中 unsafe 關(guān)鍵字和指針的使用:
using System; namespace jb51.net { ? ? class Demo ? ? { ? ? ? ? static unsafe void Main(string[] args) ? ? ? ? { ? ? ? ? ? ? double f = 3.1415; ? ? ? ? ? ? double* p = &f; ? ? ? ? ? ? Console.WriteLine("數(shù)據(jù)的內(nèi)容是: {0} ", ?f); ? ? ? ? ? ? Console.WriteLine("數(shù)據(jù)在內(nèi)存中的地址是: {0}", ?(int)p); ? ? ? ? ? ? Console.ReadKey(); ? ? ? ? } ? ? } }
運(yùn)行結(jié)果如下:
字符串的內(nèi)容是: 3.1415
字符串在內(nèi)存中的地址是: 11530344
提示:在編譯上述代碼時需要在編譯命令中添加-unsafe,例如csc -unsafe demo.cs。
使用指針檢索數(shù)據(jù)的值
在 C# 中,我們可以使用 ToString() 來獲取指針變量所指向的數(shù)據(jù)的值,如下例所示:
using System; namespace jb51.net { class Demo { public static void Main() { unsafe { int var = 123456; int* p = &var; Console.WriteLine("變量 var 的值為: {0} " , var); Console.WriteLine("指針 p 指向的值為: {0} " , p->ToString()); Console.WriteLine("指針 p 的值為: {0} " , (int)p); } Console.ReadKey(); } } }
運(yùn)行結(jié)果如下:
變量 var 的值為: 123456
指針 p 指向的值為: 123456
指針 p 的值為: 13889084
將指針作為參數(shù)傳遞給函數(shù)
我們可以將指針變量作為參數(shù)傳遞給函數(shù),如下例所示:
using System; namespace jb51.net { class Demo { public unsafe void swap(int* p, int *q) { int temp = *p; *p = *q; *q = temp; } public unsafe static void Main() { Demo p = new Demo(); int var1 = 10; int var2 = 20; int* x = &var1; int* y = &var2; Console.WriteLine("調(diào)用 Swap 函數(shù)前: var1:{0}, var2: {1}", var1, var2); p.swap(x, y); Console.WriteLine("調(diào)用 Swap 函數(shù)后: var1:{0}, var2: {1}", var1, var2); Console.ReadKey(); } } }
運(yùn)行結(jié)果如下:
調(diào)用 Swap 函數(shù)前: var1:10, var2: 20
調(diào)用 Swap 函數(shù)后: var1:20, var2: 10
使用指針訪問數(shù)組元素
在 C# 中,數(shù)組和指向該數(shù)組且與數(shù)組名稱相同的指針是不同的數(shù)據(jù)類型,例如int* p和int[] p就是不同的數(shù)據(jù)類型。您可以增加指針變量 p 的值,因?yàn)樗趦?nèi)存中不是固定的,但數(shù)組地址在內(nèi)存中是固定的,因此您不能增加數(shù)組 p 的值。如果您需要使用指針變量訪問數(shù)組數(shù)據(jù),可以像我們在 C 或 C++ 中所做的那樣,使用 fixed 關(guān)鍵字來固定指針。下面通過示例演示一下:
using System; namespace jb51.net { class Demo { public unsafe static void Main() { int[] list = {10, 100, 200}; fixed(int *ptr = list) /* 顯示指針中數(shù)組地址 */ for ( int i = 0; i < 3; i++) { Console.WriteLine("list[{0}] 的內(nèi)存地址為:{1}",i,(int)(ptr + i)); Console.WriteLine("list[{0}] 的值為:{1}", i, *(ptr + i)); } Console.ReadKey(); } } }
運(yùn)行結(jié)果如下:
list[0] 的內(nèi)存地址為:51981272
list[0] 的值為:10
list[1] 的內(nèi)存地址為:51981276
list[1] 的值為:100
list[2] 的內(nèi)存地址為:51981280
list[2] 的值為:200
編譯不安全代碼
為了編譯不安全代碼,在編譯時必須使用unsafe命令,例如編譯包含不安全代碼的 demo.cs 程序的命令如下所示:
csc /unsafe demo.cs
或
csc -unsafe demo.cs
如果您使用的是 Visual Studio,那么您需要在項(xiàng)目屬性中啟用不安全代碼,具體步驟如下:
- 通過雙擊資源管理器(Solution Explorer)中的屬性(properties)節(jié)點(diǎn),打開項(xiàng)目屬性(project properties);
- 點(diǎn)擊 Build 標(biāo)簽頁;
- 選擇選項(xiàng)“Allow unsafe code”。
到此這篇關(guān)于C#指針變量與unsafe的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C#指針變量與unsafe內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#通過WIN32 API實(shí)現(xiàn)嵌入程序窗體
這篇文章主要介紹了C#通過WIN32 API實(shí)現(xiàn)嵌入程序窗體的方法,涉及WIN32 API的調(diào)用及窗體的設(shè)計(jì),具有很好的借鑒價值,需要的朋友可以參考下2014-09-09

c# 在windows服務(wù)中 使用定時器實(shí)例代碼