黑馬程序員-.NET基礎之指針

------- Windows Phone 7手機開發.Net培訓、期待與您交流! -------

 

從大學剛開始接觸編程語言C,就知道指針這個東西,用好了,得心應手,用不好,則整個編寫的應用程序都會崩潰,爲了保持類型安全,默認情況下,C# 不支持指針,然而C#通過使用 unsafe 關鍵字,可以定義不安全上下文,然後在不安全上下文中使用指針,在 C# 中,爲了編譯不安全代碼,必須用 /unsafe 編譯應用程序。

 

一、指針類型的聲明

type* identifier;
void* identifier;   // 允許但不推薦使用!
可以聲明爲指針類型的數據類型包括:

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

任何枚舉類型。

任何指針類型。

僅包含非託管類型的字段的任何用戶定義的結構類型。下面給出一個示例。

using System;
namespace CSharpPractice.Pointer
{
    unsafe class VoidPointer
    {
        static void Main()
        {
            //pv 是指向未知類型的指針,pi 是指向整數的指針
            //注意:一元間接尋址運算符“*”不能用於 void 指針
            //使用強制轉換將 void 指針轉換爲整數(int)指針類型
            int i = 10;
            void* pv = &i;
            int* pi = (int*)pv;
            Console.WriteLine("i={0}, pi={1:X},pv={2:X}, &i={3:X}, *pi={4}", i, (int)pi, (int)pv, (int)&i, *pi);
        }
    }
}


 

二、指針的操作

下面的示例給出的是不安全的上下文中針對指針執行的運算符和語句 。

using System;
namespace CSharpPractice.Pointer{
    struct CoOrds  // 平面座標
    {
        public int x;
        public int y;
    }

    unsafe class PointerOp
    {
        static void Main()
        {
            //(1)獲取變量的地址和變量的值,並通過指針操作更改變量的值
            int number=10;
            // 將整數number的地址賦給指針變量pi:
            int* pi = &number;
            // 打印整數number原始的值:
            Console.WriteLine("整數number原始的值 = {0}", number);
            // 打印*p原始的值:
            Console.WriteLine("*pi原始的值 = {0}", *pi);
            // 打印pi的值(即整數number的地址):
            Console.WriteLine("pi(即整數number的地址) = {0:X}", (int)pi);
            // 通過指針操作更改整數number的值
            *pi = 20;
            // 打印*p的值:
            Console.WriteLine("指針操作後*pi的值 = {0}", *pi);
            // 打印整數number更改後的值:
            Console.WriteLine("指針操作後整數number的值 = {0}", number);
            
            //(2)通過指針訪問成員
            CoOrds school;  // 學校座標
            CoOrds* p = &school;
            p->x = 25;     // 學校座標x
            p->y = 12;     // 學校座標y
            Console.WriteLine("\n(p->x形式打印)學校的座標值 :  x={0}, y={1}", p->x, p->y);
            //表達式 p->x 等效於表達式 (*p).x,使用這兩個表達式可獲得相同的結果
            Console.WriteLine("(*p).x形式打印)學校的座標值 :  x={0}, y={1}", (*p).x, (*p).y);

            //(3)通過指針訪問數組元素
            char* charPointer = stackalloc char[123]; //在堆棧上分配內存
            for (int i = 65; i < 123; i++)
            {
                //charPointer[i] = (char)i; // 等價於 *(charPointer+i) = (char)i;
                *(charPointer+i) = (char)i;
            }
            // 打印大寫字母:
            Console.WriteLine("\n大寫字母:");
            for (int i = 65; i < 91; i++)
            {
                //Console.Write(charPointer[i]); // 等價於 Console.Write(*(charPointer+i));
                Console.Write(*(charPointer+i));
            }

            // 打印小寫字母:
            Console.WriteLine("\n小寫字母:");
            for (int i = 97; i < 123; i++)
            {
                Console.Write(charPointer[i]);
            }
            Console.WriteLine("\n");

            //(4)遞增和遞減指針
            // 通過將指針增加 int 的大小來遍歷一個數組。
                // 對於每一步,均顯示數組元素的內容和地址。
            int[] numbers = { 0, 1, 2, 3, 4 };
            // 將數組地址賦給指針:
            fixed (int* p1 = numbers)  //臨時固定一個變量,以獲取其地址
            {
                // 遍歷數組元素:
                for (int* p2 = p1; p2 < p1 + numbers.Length; p2++)
                {
                    Console.WriteLine("數組元素的內容:{0}, 地址:{1:X}", *p2, (int)p2);
                }
            }

            //(5)使用算術運算符 + 和 - 來操作指針
            int* memory = stackalloc int[30];
            long* difference;
            int* pi1 = &memory[4];
            int* pi2 = &memory[10];
            difference = (long*)(pi2 - pi1);
            Console.WriteLine("\n指針(&memory[10]-&memory[4])相減的差爲: {0}\n", (long)difference);

            //(6)指針比較
            int x = 234;
            int y = 236;
            int* px = &x;
            int* py = &y;
            Console.WriteLine("x爲{0}, y爲{1}, px爲{2:X}, py爲{3:X}", x ,y, (int)px, (int)py);
            Console.WriteLine("指針比較:px>py爲{0}, px<py爲{1}",  px > py,  px < py);
        }
    }
}


關於指針的筆記就寫到這裏,其實要想學好指針,光這些基礎編程是遠遠不夠的,需要我們在做實際項目中去運用,怎麼用,如何用,出現問題怎麼解決都值得我們去思考。

 

------- Windows Phone 7手機開發.Net培訓、期待與您交流! -------

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章