尘叶心繁

C#6.0-7.3 unsafe 不安全块的使用

发表于:2019/8/28 17:40

unsafe关键字相信很多朋友都没有用到过

今天特此来讲一下


1.在unsafe中可以调用指针这是非常重要的一点


   1   简单的案例:


static int Main(string[] args)
{
    int i = 0;
    unsafe
    {
        int* ip = &i;
        Console.WriteLine("scroce i address:{0:x} value:{1}", (int)ip, i);
    }
}


案例过程:

    (1) 可以看到我们用一个指针变量ip把 int 类型 i 的指针给存起来了

    (2) 然后将其指针 ip 和  i 的值打印了出来


案例结果:


   2   string和结构体使用的案例:


struct People
{
    public int Id;
    unsafe public char* Name;
    unsafe public char* Remark;
}
//或 注意类是不能使用的
unsafe struct PeopleTwo
{
    public int Id;
    public char* Name;
    public char* Remark;
}
//主方法
static void Main(string[] args)
{
    string therename = "hb";
    string thereRemark = "patter good";
    unsafe
    {
        //第一部分 开始
        fixed(char* charname = therename)
        {
            Console.WriteLine("New scroce remark address:0x{0:x} ,And the value is {1}", (int)charname,*charname);
        }
        //第一部分 结束
        //第二部分 开始
        Console.WriteLine("next is People struct");
        People per = new People();
        per.Id = 4;
        People* p = &per;
        fixed (char* twoName = therename, tworemark = therename)
        {
            //赋值操作
            p->Name = twoName;
            p->Remark = tworemark;
            //然后
            Console.WriteLine("The struct p address:0x{0:x} ", (int)p);
            Console.WriteLine("And port 'Name' address is 0x{0:x},value is {1}", (int)p->Name,*p->Name);
            Console.WriteLine("And port 'Remark' address is 0x{0:x},value is {1}", (int)p->Name, *p->Name);
        }
        //第二部分 结束
    }
}


案例过程:

    第一部分:

        (1) 首先声明 therename 和 thereRemark 变量

        (2) 然后到unsafe不安全块中,定义一个 charname 的字符指针变量进行接收

        (3) 然后进行输出 指针地址 与 值

        (4)我们可以发现这个值只输出了一个字符,因为这里存储的是 char 类型的指针变量,所以一个指针只对应一个字符

        后面会讲如何全部输出!!!


【Note】:fixed 我的理解是让 char* 接收到 string 的特殊方法


    第二部分:

        (1) 我们声明了一个 People结构体变量 per 并用一个 p 的同结构指针去接收

        (2) 然后用 twoName 与 tworemark 字符指针分别去接收 therenamethereRemark

        (3) 最后赋值给机构 p ,然后对其进行输出


案例结果:



2.处理指针字符变量转string类型


   1   在这里我写了一个简单的方法:


static void Main(string[] args)
{
    string therename = "hb";
    string thereRemark = "patter good";
    unsafe
    {
        People per = new People();
        per.Id = 4;
        People* p = &per;
        SetValue(p, therename, thereRemark);
    }
}
unsafe public static void SetValue(People* p, string name, string remark)
{
    fixed (char* therename = name, thereremark = remark)
    {

        Console.WriteLine("scroce name address:{0:x}", (int)therename);
        Console.WriteLine("scroce remark address:{0:x}", (int)thereremark);
        p->Name = therename;
        p->Remark = thereremark;

        Console.WriteLine("new name address:{0:x}", (int)(p->Name));
        Console.WriteLine("new remark address:{0:x}", (int)(p->Remark));

        string newname = GetString(p->Name);
        Console.WriteLine($"variable newname value is:{newname}");
        string newremark = GetString(p->Remark);
        Console.WriteLine($"variable newname value is:{newremark}");
    }
}
//处理指针字符变量转string类型
unsafe public static string GetString(char* one)
{
    StringBuilder str = new StringBuilder();
    if (one == null)
    {
        return "";
    }
    char** text = &one;
    {
        while (*text != null)
        {
            if (**text == '\0')
            {
                break;
            }
            str.Append(**text);
            *text = ++(*text);
        }

    }
    return str.ToString();
}


案例分析:

    主要将一下GetString()

        首先我要知道字符串是一个字符的数组组成的。

        通过 text 二级指针去获取指针变量 one 的指针,循环判断指针是否为空,如果不为空着用 StringBuilder循环添加起来,

        当返回值为 '\0' 着表示该指针已经走完了,最后返回结果


案例结果:


3.c/c++扩展




   1   maclloc的使用与声明:

People* p2 = stackalloc People[1];


说明:我们知道在 c/c++中,声明动态内存并分配到到站的函数是 maclloc

          所以在这里我们可以用 stackalloc 来进行直接创建



如有更多关注请访问:https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/language-specification/unsafe-code


谢谢!




关于TNBLOG
TNBLOG,技术分享
App store Android
精彩评论
{{item.replyName}}
{{item.content}}
{{item.time}}
{{subpj.replyName}}
@{{subpj.beReplyName}}{{subpj.content}}
{{subpj.time}}
猜你喜欢