这些函数是对内存空间操作的,就是把内存块,内存空间里面的数据进行拷贝;

1、memcpy

memcpy的参数:

  1. 第一个参数是目标地址,接收拷贝的数据
  2. 第一个参数是,源地址,要拷贝数据的地址
  3. num是一共要拷贝多少个字节
  4. 返回类型也是void* 返回的是目标地址

为什么参数都是void*的指针,因为一块内存空间可能存放不同类型的值,float,struct;所以用void*接收跟合理

就是把arr里的前5*sizeof(int)字节的数据,拷贝到arr1里;

memcpy实现:

  1. 按照原型写参数
  2. 为什么memcpy最后一个参数是num字节数?,因为不知道要怎么拷贝过去,那好了,既然知道一共要拷贝多少字节,干脆直接把要拷贝内存空间切成一份份,一个字节,一个字节一个字节的交换;
  3. while循环要交换的字节数,直接交换是不行的;要强制类型装换;往后++继续交换;
  4. 最后返回的是dest,目标地址arr1;

但是能不能自己拷贝自己呢?答案是不行的;

当使用自己的my_memcpy拷贝数据的是否,自己拷贝自己,内存空间上会重叠,是会有错的;

比如把12345,拷贝放到34567;当前面逐个拷贝的时候,3、4已经覆盖了,再继续往后找也是1、2;内存空间重叠发生错误了;

但是有的朋友直接用memcpy不会发生这种情况;我用的是自己实现模拟的memcpy,是满足memecpy的标准的;我用的编译器是vs2022;直接用memcpy也解决的这种问题,但是不是所有的编译器都是能这样做的;memcpy本身是不支持的,只是我这vs2022或者你的编译器,更优秀给你实现出来的;不是全部memcpy都能实现出来的;

如是这种内存空间发生重叠的情况,我们最好使用memmove;

2、memmove

memmove是考虑了内存空间重叠的情况;内存空间重叠的时候,交换的数据不会被覆盖;

参数:

  1. 第一个参数目标地址
  2. 第二个参数是源数据地址
  3. 要交换的字节数
  4. 返回的是目标地址

跟memcpy的用法是一样的,交换的时候数据是不会被覆盖的;

memmove的实现:

1、memmove可能创建了一个数组,先拷贝存放了原有的数据,再去拿去arr移动数据;但是我们用另外一种方法,在同一块内存空间去操作;

2、一种情况,dest目标数组在src源数组的后面,这里我们就不能用从src前面开始拷贝,要从src后面开始拷贝,这样拷贝的时候5和6就不会被覆盖了;

3、另一种情况就是在dest目标数组在src源数组前面,就用src从前往后拷贝,如果从后面拷贝,5和6就会被覆盖;

4、看来dest在src的那个位置是有讲究的,在src前面就是前->后,在src的区域就是后->前,如果是完全跟src不在用一个位置,那前->后,前->后都行;但是我们这里就分为两个条件简单一些,在src前面就是前->后,在src的区域就是后->前;

先判断是在src前面;就是前->后;也就是把内存空间拆分一个一个字节,再地址强制类型转换,一个一个交换,交换num次;

不是在src前面就是后->前交换,再拆分,但是这是从内存空间后面开始交换,第一次循环num是20,因为是后置--,进来后--,然后src+num,其实加得是19,src+num取得就是最后一个字节,dest是一样得;随着num逐渐变小,往后--,交换一个一个字节;

3、menset

对内存空间里得值,按照多少字节进行设置;

  1. 第一个参数要设置得内存地址
  2. 第二个参数是要设置的值
  3. 要设置多少字节
  4. 返回类型是void*

比如把arr给全部置为0,就是arr地址,设置的值,设置40个字节;它是按照字节来给你设置的;也就是说每个字节都是0,不是每个元素都是0;

比如全部设置为1,不是每个元素设置为1;而是每个字节设置为1;

4、mencmp

对内存空间里的多少个字节,进行比较;

  1. 两个要比较的内存空间:ptr1和ptr2;
  2. num表示要比较的字节数
  3. 返回的结果跟stccmp、strncmp的结果是一样的

可以看出来,按字节比较,比较16个字节,就是比较4和3,arr比arr1大,返回大于0的数;

那如果我们按照上面的例子比较13个字节;

它再内存中的存储是这样的,当时第13个字节的时候,04比03;还是arr比arr1大;

感谢观看

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐