博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C#中指针的用法
阅读量:5360 次
发布时间:2019-06-15

本文共 2567 字,大约阅读时间需要 8 分钟。

(*) unsafe 和 fixed

unsafe{                   int[] array = new int[10];    for (int i = 0; i < array.Length; i++)    {        array[i] = i;    }    fixed (int* p = array)     {        for (int i = 0; i < array.Length; i++)        {            System.Console.WriteLine(p[i]);        }                        }               }

指针在c#中是不提倡使用的,有关指针的操作被认为是不安全的(unsafe)。因此运行这段代码之前,先要改一个地方,否则编译不过无法运行。

修改方法:在右侧的solution Explorer中找到你的项目,在项目图标(绿色)上点右键,选最后一项properties,然后在Build标签页里把Allow unsafe code勾选上。之后这段代码就可以运行了,你会看到,上面这段代码可以像C语言那样用指针操纵数组。但前提是必须有fixed (int* p = array),它的意思是让p固定指向数组array,不允许改动。因为C#的自动垃圾回收机制会允许已经分配的内存在运行时进行位置调整,如果那样,p可能一开始指的是array,但后来array的位置被调整到别的位置后,p指向的就不是array了。所以要加一个fixed关键字,把它定在那里一动不动,之后的操作才有保障。

 

另有两点需要注意:

 

1)指针的使用必须放在unsafe的区域里;unsafe关键字也可作为类或方法的修饰符。

 

2)fixed (int* p = array)中,p的定义不能写在别处,而且fixed关键字也只能在unsafe区域里使用。

(*) 略简洁的unsafe写法

class Program    {        unsafe public static UInt16 Htons(UInt16 src)         {            UInt16 dest;            // 不能照搬C的源代码,因为有些类型长度不一样,如char(2字节),long(8字节)            // ((char*)&dest)[0] = ((char*)&src)[1];            // ((char*)&dest)[1] = ((char*)&src)[0];            ((byte*)&dest)[0] = ((byte*)&src)[1];            ((byte*)&dest)[1] = ((byte*)&src)[0];            return dest;        }        public static UInt16 ConciseHtons(UInt16 src)         {            UInt16 dest;            unsafe            {                ((byte*)&dest)[0] = ((byte*)&src)[1];                ((byte*)&dest)[1] = ((byte*)&src)[0];            }                        return dest;        }                static void Main()         {            UInt16 val = 1;            // 如果方法是unsafe的,则必须在unsafe block里调用            unsafe            {                                val = Htons(val);            }            Console.WriteLine(val);            // 更简洁的写法是把unsafe block写在函数内部            val = ConciseHtons(val);            Console.WriteLine(val);        }                    }

(*) stackallocstackalloc的用处仅仅是把数组分配在栈上(默认是分配在托管堆上的)。

class MyClass    {        public int val;    }    class Program    {                        static void Main()         {                        unsafe            {                                MyClass *p = stackalloc MyClass[1]; // Error!! 如果类型要放在托管堆上则不行,如果MyClass是struct就OK了                p->val = 1;                int *iArray = stackalloc int[100];  // OK,在栈上创建数组, int类型本身就是放在栈上的            }                    }                    }

注意:指针指向的内存一定要固定。凡是C#里的引用类型(一切类型的数组都是引用类型)都是分配在托管堆上的,都不固定。有两种方法强制固定,一种是用stackalloc分配在栈上,另一种是用fixed分配在堆上。

 

转载于:https://www.cnblogs.com/QimmyPeng/p/4215959.html

你可能感兴趣的文章
周记2018.8.27~9.2
查看>>
MySQL中 1305-FUNCTION liangshanhero2.getdate does not exit 问题解决
查看>>
Ctrl+Alt+Down/Up 按键冲突
查看>>
python序列化和json
查看>>
mongodb
查看>>
网格与无网格
查看>>
2018年3月份
查看>>
SSH-struts2的异常处理
查看>>
《30天自制操作系统》学习笔记--第14天
查看>>
LGPL协议的理解
查看>>
1、Python基础
查看>>
Unity The Tag Attribute Matching Rule
查看>>
试着理解下kvm
查看>>
WebService学习总结(二)--使用JDK开发WebService
查看>>
Tizen参考手机RD-210和RD-PQ
查看>>
竞价广告系统-位置拍卖理论
查看>>
策略模式 C#
查看>>
[模板]树状数组
查看>>
[HDU 6447][2018CCPC网络选拔赛 1010][YJJ's Salesman][离散化+线段树+DP]
查看>>
设计模式学习的好方法
查看>>