C# 允許在代碼塊的函數(shù)中使用指針變量來(lái)標(biāo)記不安全的修飾符。不安全代碼或非托管代碼是使用指針變量的代碼塊。
指針是一個(gè)變量,其值是另一個(gè)變量的地址,即存儲(chǔ)器位置的直接地址。 類(lèi)似于任何變量或常量,要使用指針必須先聲明指針,然后才能使用它來(lái)存儲(chǔ)任何變量地址。
指針聲明的一般形式是:
type *var-name;
以下是有效的指針聲明:
int *ip; /* pointer to an integer */
double *dp; /* pointer to a double */
float *fp; /* pointer to a float */
char *ch /* pointer to a character */
以下示例說(shuō)明如何在 C# 中使用指針,使用不安全的修飾符:
using System;
namespace UnsafeCodeApplication
{
class Program
{
static unsafe void Main(string[] args)
{
int var = 20;
int* p = &var;
Console.WriteLine("Data is: {0} ", var);
Console.WriteLine("Address is: {0}", (int)p);
Console.ReadKey();
}
}
}
當(dāng)上述代碼通過(guò)編譯并執(zhí)行后,會(huì)產(chǎn)生以下結(jié)果:
Data is: 20
Address is: 890153869
不必將整個(gè)方法聲明為不安全,也可將代碼的一部分聲明為不安全。下一節(jié)中的示例顯示了這一點(diǎn)。
可以使用ToString()
方法檢索由指針變量引用的位置處存儲(chǔ)的數(shù)據(jù)。以下示例演示如下:
using System;
namespace UnsafeCodeApplication
{
class Program
{
public static void Main()
{
unsafe
{
int var = 20;
int* p = &var;
Console.WriteLine("Data is: {0} " , var);
Console.WriteLine("Data is: {0} " , p->ToString());
Console.WriteLine("Address is: {0} " , (int)p);
}
Console.ReadKey();
}
}
}
當(dāng)編譯和執(zhí)行上述代碼時(shí),會(huì)產(chǎn)生以下結(jié)果:
Data is: 20
Data is: 20
Address is: 97122341
可以將指針變量傳遞給方法作為參數(shù)。以下示例說(shuō)明了這一點(diǎn):
using System;
namespace UnsafeCodeApplication
{
class TestPointer
{
public unsafe void swap(int* p, int *q)
{
int temp = *p;
*p = *q;
*q = temp;
}
public unsafe static void Main()
{
TestPointer p = new TestPointer();
int var1 = 10;
int var2 = 20;
int* x = &var1;
int* y = &var2;
Console.WriteLine("Before Swap: var1:{0}, var2: {1}", var1, var2);
p.swap(x, y);
Console.WriteLine("After Swap: var1:{0}, var2: {1}", var1, var2);
Console.ReadKey();
}
}
}
當(dāng)上述代碼被編譯并執(zhí)行時(shí),它產(chǎn)生以下結(jié)果:
Before Swap: var1: 10, var2: 20
After Swap: var1: 20, var2: 10
在 C# 中,一個(gè)數(shù)組名稱(chēng)和一個(gè)與數(shù)組數(shù)據(jù)類(lèi)型相同的數(shù)據(jù)類(lèi)型的指針是不一樣的變量類(lèi)型。 例如,int * p
和int [] p
是兩個(gè)不一樣的類(lèi)型。我們可以增加指針變量p
,因?yàn)樗趦?nèi)存中不是固定的,而數(shù)組的地址是固定在內(nèi)存中,所以不能增加。
因此,如果您需要使用指針變量來(lái)訪問(wèn)數(shù)組數(shù)據(jù),如傳統(tǒng)上在C語(yǔ)言或C++(請(qǐng)查閱:C指針)中所做的那樣,則需要使用fixed
關(guān)鍵字修復(fù)指針。
以下示例演示如下:
using System;
namespace UnsafeCodeApplication
{
class TestPointer
{
public unsafe static void Main()
{
int[] list = {10, 100, 200};
fixed(int *ptr = list)
/* let us have array address in pointer */
for ( int i = 0; i < 3; i++)
{
Console.WriteLine("Address of list[{0}]={1}",i,(int)(ptr + i));
Console.WriteLine("Value of list[{0}]={1}", i, *(ptr + i));
}
Console.ReadKey();
}
}
}
當(dāng)編譯和執(zhí)行上述代碼時(shí),會(huì)產(chǎn)生以下結(jié)果:
Address of list[0] = 31627168
Value of list[0] = 10
Address of list[1] = 31627172
Value of list[1] = 100
Address of list[2] = 31627176
Value of list[2] = 200
要編譯不安全的代碼,必須使用命令行編譯器指定/unsafe
命令行開(kāi)關(guān)。
例如,要編譯一個(gè)名稱(chēng)為prog1.cs
的源代碼中包含不安全代碼,請(qǐng)從命令行中輸入命令:
csc /unsafe prog1.cs
如果您使用的是Visual Studio IDE,則需要在項(xiàng)目屬性中啟用不安全的代碼。
參考以下步驟: