.NET中的指针类型

        了解.NET的人都知道其定义了两种数据类型:值类型和引用类型。实际上还有第三种:指针类型。要使用指针类型,系统为我们提供了特定的操作符和关键字,可以绕开CLR的内存管理机制,自己处理。

指针相关的操作符和关键字
*
该操作符用于创建一个指针变量(也就是一个表示直接内存位置的变量)。和在C/C++中一样,同样的操作符用于指针间接寻址
&
获取内存中变量的地址
->
访问一个由指针表示的类型的字段(C#的不安全版本)
[ ]
在不安全的上下文中[ ]索引指针变量指向的位置
++, --
不安全上下文中,可递增递减
+,-
加减运算符
==,!=,<,>,<=,=>
比较和相等
stackallo
直接在栈上分配C#数组
fiexd
临时固定一个变量以使他的地址可以被找到
.NET使用指针类型的情况很少,一般使用指针有两种情形

   1要绕过CLR管理直接操作指针以优化应用程序的特定部分

   2要调用基于C的.dll或调用需要指针作为参数的COM服务器。即使在这种情况下,为了支持System.IntPr类型和System.Runtime.InteropServices.Marshal类型,也可以不使用指针。

编写非安全代码时,需要将项目属性中生的的允许不安全代码打勾


代码里需添加unsafe关键字

 static void Main(string[] args)
        {
            unsafe
            {
                //在此处理指针类型
            }

            //在此处不可以处理指针类型
        }

除了声明代码块为不安全代码外,还可构建“不安全的”结构,类,类型和成员参数。

     unsafe struct Node
        {
            //整个结构都是不安全的
            public int Value;
            public Node* Left;
            public Node* Right;
        }


        unsafe struct Node2
        {
            //结构安全,但Node2成员不安全
            public int Value;
            public unsafe Node2* Left;
            public unsafe Node2* Right;
        }

静态方法或实例方法都可以被标记为不安全。如果不想强制调用者将调用封装进不安全上下文,可以利用unsafe关键字修改Main().

 unsafe static void Main(string[] args)
        {
            int myInt2 = 5;
            zhizhen(&myInt2);
            Console.WriteLine(myInt2);
            Console.ReadKey();
        }

        unsafe static void zhizhen(int* myIntPointer)
        {
            *myIntPointer *= *myIntPointer;
        }

建立了不安全上下文后,可以使用*操作符构建数据类型的指针,使用&操作符获取被指向的内存的地址。

声明指针变量


stackallo关键字

在不安全上下文中,可能需要声明一个直接从调用栈分配内存(不受制于.NET垃圾收集器)的本地变量。C#提供了与C运行函数库_alloca等效的stackalloc关键字来满足这个需求.

        unsafe static void UnsafeStackalloc()
        {
            char* p = stackalloc char[256];
            for (int k = 0; k < 256; k++)
                p[k] = (char)k;
        }

使用fixed关键字固定类型

为了将不安全上下内存中的引用类型变量固定,C#提供了fixed关键字。fixed语句设置向托管类型的的指针并在代码执行过程中固定该变量。由于垃圾收集器将在不可预知的情况下重置变量,没有fixed的话。托管变量的指针将没有多大用处。

  unsafe static void UseAndPinPoint()
        {
            PointRef pt = new PointRef();
            pt.x = 5;
            pt.y = 6;

            //在适当的位置固定变量
            fixed (int* p = &pt.x)
            {
                //在此使用int变量
            }
            Console .WriteLine ("{0}",pt);
        }

        class PointRef
        {
            public int x;
            public int y;
            public override string ToString()
            {
                return string.Format("({0},{1})", x, y);
            }
        }

sizeof关键字

sizeof用来获取值类型的字节大小。

     unsafe static void UnseofSizeod()
        {
           Console.WriteLine ("{0}",sizeof (short ));
        }

猜你喜欢

转载自blog.csdn.net/m0_37137902/article/details/80677191