0%

C# 委托


  • 委托的概念

 委托是一个类,它定义了方法的类型,使一个方法可以当作另一个方法的参数来进行传递,这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。。

  • 常见委托的使用

    1
    2
    3
    4
    > delegate int MethodDelegate(int x,inty);
    >
    > MethodDelegate method = new MethodDelegate(function_name);
    >
    1
    2
    >  MethodDelegate method = function_name;
    >

    将对应的函数名放入function_name位置,函数的签名需要和委托声明的一样。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    > //使用匿名方法
    > MyDelegate myDelegate = delegate(int x, int y)
    > {
    > return x + y;
    > };
    >
    > //使用Lambda表达式
    > MyDelegate myDelegateLambda = (int x, int y) => { return x + y; };
    >
  • 其他委托的分类

    1.Action

    Action作为一种反省委托,不具备返回值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    static void Main(string[] args)
    {
    Test<string>(Action,"Hello World!");
    Test<int>(Action, 1000);
    Test<string>(p => { Console.WriteLine("{0}", p); }, "Hello World");
    //使用Lambda表达式定义委托
    Console.ReadKey();
    }
    public static void Test<T>(Action<T> action, T p)
    {
    Action(p);
    }
    private static void Action(string s)
    {
    Console.WriteLine(s);
    }
    private static void Action(int s)
    {
    Console.WriteLine(s);
    }

    2.Func

    Func是返回值的泛型委托

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    static void Main(string[] args)
    {
    Console.WriteLine(Test<int,int>(Fun,100,200));
    Console.ReadKey();
    }
    public static int Test<T1, T2>(Func<T1, T2, int> func, T1 a, T2 b)
    {
    return func(a, b);
    }
    private static int Fun(int a, int b)
    {
    return a + b;
    }

    3.predicate

    predicate是返回值bool的泛型委托

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public delegate int MethodDelegate(int x, int y);
    private static MethodDelegate method;
    static void Main(string[] args)
    {
    method = new MethodDelegate(Add);
    Console.WriteLine(method(10,20));
    Console.ReadKey();
    }

    private static int Add(int x, int y)
    {
    return x + y;
    }
  • 委托的好处

    1. 相当于用方法作为另一方法参数(类似于C的函数指针)

    2. 在两个不能直接调用的方法中作为桥梁,如:在多线程中的跨线程的方法调用就得用委托

    3. 当不知道方法具体实现什么时使用委托,如:事件中使用委托

  • 注意事项与特点

     1. 虽然委托的定义有点像方法的声明,但是委托是属于类的层面。

     2. 委托类似于C++的函数指针,但是它是类型安全的

     3.委托允许将方法作为参数进行传递。

     4. Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型

     5. Func可以接受0个至16个传入参数,必须具有返回值

     6. Action可以接受0个至16个传入参数,无返回值

     7 Predicate只能接受一个传入参数,返回值为bool类型

相关博客:

分分钟用上C#中的委托和事件 (该文学习将委托是事件结合,从而实现一个对象发送指令,其他的对象根据不同指令进行自己的操作的功能)

Thanks to Danny Chen

.HEX file


HEX 文件介绍

 Keil HEX文件是由一行行符合Intel HEX文件格式的文本所构成的ASCII文本文件。在Intel HEX文件中,每一行包含一个HEX记录。这些记录由对应机器语言码和/或常量数据的十六进制编码数字组成。Intel HEX文件通常用于传输将被存于ROM或者EPROM中的程序和数据。大多数EPROM编程器或模拟器使用Intel HEX文件。

文件解析

  • 记录格式
     Intel HEX由任意数量的十六进制记录组成。每个记录包含5个域,它们按以下格式排列:

    :llaaaatt[dd…]cc

     每一组字母对应一个不同的域,每一个字母对应一个十六进制编码的数字。每一个域由至少两个十六进制编码数字组成,它们构成一个字节,如下描述:

    符号 符号意义
    : 每个Intel HEX记录都由冒号开头.
    ll 数据长度域,它代表记录当中数据字节(dd)的数量.
    aaaa 地址域,它代表记录当中数据的起始地址.
    tt 是代表HEX记录类型的域,它可能是以下数据当中的一个:
    > 00 – 数据记录
    > 01 – 文件结束记录
    > 02 – 扩展段地址记录
    > 04 – 扩展线性地址记录
    > 05 - 运行地址记录
    dd 数据域,它代表一个字节的数据. 一个记录可以有许多数据字节.记录当中数据字节的数量必须和数据长度域(ll)中指定的数字相符.
    cc 是校验和域,它表示这个记录的校验和.校验和的计算是通过将记录当中所有十六进制编码数字对的值相加,以256为模进行以下补足.
  • 扩展线性地址记录(HEX386) :

     扩展线性地址记录也叫作32位地址记录或HEX386记录.这些记录包含数据地址的高16位.扩展线性地址记录总是有两个数据字节,外观如下:

    :02000004FFFFFC

    其中:

    数据 数据意义
    02 这个记录当中数据字节的数量
    0000 地址域,对于扩展线性地址记录,这个域总是0000.
    04 记录类型 04(扩展线性地址记录)
    FFFF 地址的高16位.
    FC 是这个记录的校验和,计算方法如下:
    >> 01h + NOT(02h + 00h + 00h + 04h + FFh + FFh).

 当一个扩展线性地址记录被读取,存储于数据域的扩展线性地址被保存,它被应用于从Intel HEX文件读取来的随后的记录.线性地址保持有效,直到它被另外一个扩展地址记录所改变.

 通过把记录当中的地址域与被移位的来自扩展线性地址记录的地址数据相加获得数据记录的绝对存储器地址.

假设:

来自数据记录地址域的地址 2462

扩展线性地址记录的数据域 + FFFF

绝对存储器地址 FFFF2462


  • 扩展段地址记录(HEX386) :

     扩展段地址记录也叫HEX86记录,它包括4-19位数据地址段.扩展段地址记录总是有两个数据字节,外观如下:

    :020000021200EA

    其中:

    数据 数据意义
    02 这个记录当中数据字节的数量
    0000 地址域.对于扩展段地址记录,这个域总是0000.
    02 是记录类型 02(扩展段地址记录)
    1200 1200 是地址段.
    EA 是这个记录的校验和,计算方法如下: >> 01h + NOT(02h + 00h + 00h + 02h + 12h + 00h).

 当一个扩展段地址记录被读取,存储于数据域的扩展段地址被保存,它被应用于从Intel HEX文件读取来的随后的记录.段地址保持有效,直到它被另外一个扩展地址记录所改变.

 通过把记录当中的地址域与被移位的来自扩展段地址记录的地址数据相加获得数据记录的绝对存储器地址.

以下的例子演示了这个过程.

来自数据记录地址域的地址 2462

扩展段地址记录数据域 + 1200 <<1

绝对存储器地址 00014462


  • 文件结束(EOF)记录(HEX386) :

     Intel HEX文件必须以文件结束(EOF)记录结束.这个记录的记录类型域的值必须是01.EOF记录外观总是如下:

    :00000001FF

    其中:

    数据 数据意义
    00 这个记录当中数据字节的数量
    0000 是数据被下载到存储器当中的地址.在文件结束记录当中地址是没有意义被忽略的.0000h是典型的地址.
    01 记录类型 01(文件结束记录)
    FF 这个记录的校验和,计算方法如下:
    >> 01h + NOT(00h + 00h + 00h + 01h).
  • 文件整体分析

    第一行 :02 0000 04 0800 F2

    第二行 :10 0000 00 7806002051040008690200086B020008 0D

      注意:地址是大开端,0800+0000 = 0x08000000

      78060020是MSP初始值,其实为0x20000678,是小开端。

      51040008 = 08000451 reset isr地址

1
2
3
4
5
6
7
151:             LDR     R0, =SystemInit   ß-----------resetHandle

0x08000450 4809 LDR r0,[pc,#36] ; @0x08000478

152: BLX R0

0x08000452 4780 BLX r0

倒数第二行 :04 0000 05 08000131 BD, 05表示开始运行地址,08000131是地址的值。

倒数第一行 :00 0000 01 FF,hex文档结束

 08000131为开始地址_main(),08000451为resetHandle地址,由于resethandle里面有systeminit函数,所以以resethandle为准!这两个都不用下载。

Noted


华为:

实习:

华为实习生分类(可在杭州):

​ (通用软件工程师)无线网络产品线、数据通信产品线、Cloud & AI(Cloud BU)、Cloud & AI(IT产品线)、海思半导体与器件业务部。

​ (操作系统工程师)中央软件院、中央研究院

​ (云计算开发工程师)无线网络产品线、数据通信产品线、Cloud & AI(Cloud BU)、Cloud & AI(IT产品线)、海思半导体与器件业务部、中央软件院。

语情集


信手一笔:

云志:

不知似梦似前程,信步青云脚下踩。
长途漫漫不济路,只为千里赏昙花。

望,细呷今朝淡觉甜
盼,酌品前途深作研

思乡:

洋洋溢溢归故去

摇身梦醒过辰时
身在外婆桥下走
良辰佳节惜寸金

道情:

一系扬州红绳,从此思念相瘦

十八束发成人日,一指白蜜不忍抹
两眸相视情初起,如今朝夕已四年

万卷书来不如汝之一频、一笑、一驻留。
一纸情深堪比鸳鸯百媚、千转、万间情。

Sorting


C++ 排序算法:

归并:


原理 :

​ 归并排序:采用归并的思想,分治策略。
将数据不断的进行二分,直到二分为仅一个数。回溯,两个数进行归并 之后,回溯,进行四个数据的归并。在归并时根据要求按顺序合并。依次回溯至迭代起点,归并排序就已完成。

​ 归并的过程:就是将两组顺序的数据,根据数据的大小顺序存入连续内存空间,从而使得数据有序。

代码:

Please wait the lazy man!

Review C++


### C++ 注意点记录:

数组与指针:

​ 在一定程度上,数组与指针是可以对等的,但是今天(2019-4-22)发现了一个不同。

​ 数组在想要获得元素长度的时候可以根据 sizeof(array) / sizeof(array[0]) 进行获得,而指针则不行,因为指针在32位上 sizeof(pointer) == 4;64位上sizeof(pointer) == 8; 这是sizeof在使用过程当中需要注意的问题。

​ 当然,如果用malloc 进行内存空间申请的话,可以用sizeof进行获取分配的数据长度,通过除以元素长度可获得元素个数,因为malloc会分配额外空间进行存储数据大小。

​ (malloc 语法: char *mPtr = NULL; mPtr = (char *)malloc( size * sizeof(char)); )

About this blog


目的

 希望自己能够有个记录自己学习,写些乱七八糟,甚至分享一些快乐的地方。因此我想建起互联网中属于自己的展示网站。

 该篇主要记录一下自己做这个博客的过程,方便以后重新建立。

如何建这块天地

  这样一个博客,谁都能做,仅仅需要几十块钱就能满足一年的需求,下面稍微记录怎么样搭建吧!

  像我这样想简简单单不花大价钱来进行搭建这样一个博客的话,你需要注册github账号。github能给你一个代码进行托管的平台,同时github也能为你分配一个域名。因此你可以把自己托管项目中一个作为该域名对应的网站。原理其实就这么简单。

  当然根据不同网站的需求可能会需要用到服务器空间,那就需要去各种云供应商购买云空间,那就要钱咯,如果买的是国内空间的话还需要进行备案。

为你的博客选一个模版

  在理解了整个过程的原理,其实接下来的事就很容易理解了。为了网站美观,你可以选择一个好看的模版。Jekyll上就有很多好看的模版,我也是从中选择了一个。挑中喜欢的模版,在github中可以直接fork到你的项目,然后重命名该项目为username.github.io,他将作为你域名的主页,然后就可以访问咯。

绑定自定义域名

  github提供将域名改为自定义名的功能,这样感觉网站看起来会高大上一些,hhh。

  域名可以在阿里云或者别的平台上购买,我买的是一级域名.work,挺便宜,20RMB左右一年。买了域名后在云解析控制台上进行域名转换。转换选项天CNAME,服务商填默认。解析值填工程名就OK。绑定完之后在github的工程上进行设置解析访问的自定义域名即可。

  剩下就去完善博客吧!