溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C#指針變量與unsafe如何實(shí)現(xiàn)

發(fā)布時(shí)間:2023-03-31 14:21:40 來(lái)源:億速云 閱讀:265 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹“C#指針變量與unsafe如何實(shí)現(xiàn)”,在日常操作中,相信很多人在C#指針變量與unsafe如何實(shí)現(xiàn)問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”C#指針變量與unsafe如何實(shí)現(xiàn)”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

為了保持類(lèi)型的安全性,默認(rèn)情況下 C# 是不支持指針的,但是如果使用 unsafe 關(guān)鍵字來(lái)修飾類(lèi)或類(lèi)中的成員,這樣的類(lèi)或類(lèi)中成員就會(huì)被視為不安全代碼,C# 允許在不安全代碼中使用指針變量。在公共語(yǔ)言運(yùn)行時(shí) (CLR) 中,不安全代碼是指無(wú)法驗(yàn)證的代碼,不安全代碼不一定是危險(xiǎn)的,只是 CLR 無(wú)法驗(yàn)證該代碼的安全性。因此 CLR 僅會(huì)執(zhí)行信任程序集中包含的不安全代碼。

指針變量

在 C# 中,指針同樣是一個(gè)變量,但是它的值是另一個(gè)變量的內(nèi)存地址,在使用指針之前我們同樣需要先聲明指針,聲明指針的語(yǔ)法格式如下所示:

type* var_name;

下表中列舉了一些定義指針的示例:

示例說(shuō)明
int* pp 是指向整數(shù)的指針
double* pp 是指向雙精度數(shù)的指針
float* pp 是指向浮點(diǎn)數(shù)的指針
int** pp 是指向整數(shù)的指針的指針
int*[] pp 是指向整數(shù)的指針的一維數(shù)組
char* pp 是指向字符的指針
void* pp 是指向未知類(lèi)型的指針

與聲明變量相同,我們同樣可以在一行代碼中同時(shí)聲明多個(gè)指針,如下所示:

int* p1, p2, p3;  // 定義 p1、p2、p3 三個(gè)整數(shù)指針

注意:指針類(lèi)型不能從對(duì)象中繼承,并且裝箱和拆箱也不支持指針,但是不同的指針類(lèi)型以及指針與整型之間可以進(jìn)行轉(zhuǎn)換。

【示例】下面通過(guò)示例演示 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

提示:在編譯上述代碼時(shí)需要在編譯命令中添加-unsafe,例如csc -unsafe demo.cs。

使用指針檢索數(shù)據(jù)的值

在 C# 中,我們可以使用 ToString() 來(lái)獲取指針變量所指向的數(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

使用指針訪問(wèn)數(shù)組元素

在 C# 中,數(shù)組和指向該數(shù)組且與數(shù)組名稱(chēng)相同的指針是不同的數(shù)據(jù)類(lèi)型,例如int* p和int[] p就是不同的數(shù)據(jù)類(lèi)型。您可以增加指針變量 p 的值,因?yàn)樗趦?nèi)存中不是固定的,但數(shù)組地址在內(nèi)存中是固定的,因此您不能增加數(shù)組 p 的值。如果您需要使用指針變量訪問(wèn)數(shù)組數(shù)據(jù),可以像我們?cè)?C 或 C++ 中所做的那樣,使用 fixed 關(guān)鍵字來(lái)固定指針。下面通過(guò)示例演示一下:

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

編譯不安全代碼

為了編譯不安全代碼,在編譯時(shí)必須使用unsafe命令,例如編譯包含不安全代碼的 demo.cs 程序的命令如下所示:

csc /unsafe demo.cs

csc -unsafe demo.cs

如果您使用的是 Visual Studio,那么您需要在項(xiàng)目屬性中啟用不安全代碼,具體步驟如下:

  • 通過(guò)雙擊資源管理器(Solution Explorer)中的屬性(properties)節(jié)點(diǎn),打開(kāi)項(xiàng)目屬性(project properties);

  • 點(diǎn)擊 Build 標(biāo)簽頁(yè);

  • 選擇選項(xiàng)“Allow unsafe code”。

到此,關(guān)于“C#指針變量與unsafe如何實(shí)現(xiàn)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI