• Day_15 > 内存相关的函数


    目录

    1.memcpy

    1.1memcpy函数的使用

    1.2memcpy函数的模拟实现

    2.memmove

    2.1memcpy存在的局限性

    2.2memmove函数的使用

    2.3memmove函数的模拟实现

    3.memset

    3.1memset函数的使用

    4.memcmp

    4.1memcpy函数的使用


    之前我们可能了解过字符串函数,今天我们了解一下内存相关的函数

    1.memcpy

    1.1memcpy函数的使用

    strcpy函数我们可能都知道,字符串拷贝函数,跟函数名一样,只能拷贝字符串

    但是我们知道,内存中的数据不仅仅是字符

    1. int arr1[10] = { 0 };
    2. int arr2[] = { 1,2,3,4,5 };

    比如,当我们有这么一段数据

    我们需要把arr2中的前五个整型的数据拷贝放在arr1中 

    这个时候我们就不能使用strcpy,因为他是整型数据了

    这时候我们C语言就提供了memcpy函数,同样的,我们在Reference - C++ Reference (cplusplus.com)上学习一下该函数

    void * memcpy ( void * destination, const void * source, size_t num );

     我们可以理解为,把source中的前num个字节的数据拷贝放到destination中去

    我们还是用监视窗口来看一下数据是否被拷贝

    我们可以看到确实是被拷贝过去了 

    1.2memcpy函数的模拟实现

    1. void* my_memcpy(const void* dest, const void* src, size_t sz)
    2. {
    3. assert(dest && src);
    4. while (sz--)
    5. {
    6. *(char*)dest = *(char*)src;
    7. dest=(char*)dest+1;
    8. src=(char*)src+1;
    9. }
    10. }

    运行的结果也是同样的效果

    这里我们要注意

    void*是不能直接++和--的,所以我们需要强转为char*类型,++或--跳过一个字节的空间

    void*是不能直接解引用的,所以我们需要强转为char*类型,解引用

    2.memmove

    2.1memcpy存在的局限性

    我们这个代码也是存在一定的局限性,比如下面这种情况

    将数组arr的前五个数据拷贝到arr[2]的位置,通过调试我们发现写出来的函数并不能有效的实现

    C语言的标准规定:

    不重叠内存的拷贝,可以使用memcpy,重叠内存的拷贝就不能使用了

    重叠内存的拷贝,我们可以使用memmove函数来实现 

    2.2memmove函数的使用

    同样的,我们来先学习一下memmove函数的使用

    void * memmove ( void * destination, const void * source, size_t num );

    他的参数和返回类型和memcpy一模一样,

    我们尝试使用一下memmove函数,看能否解决刚才的问题

    这样问题就很好的解决了 

    2.3memmove函数的模拟实现

    1. #include
    2. #include
    3. #include
    4. void* my_memmove(const void* dest, const void* src, size_t sz)
    5. {
    6. void* ret = dest;
    7. assert(dest && src);
    8. if (dest < src)
    9. {
    10. //前->后
    11. for(int i=0;i
    12. {
    13. *(char*)dest = *(char*)src;
    14. dest = (char*)dest + 1;
    15. src = (char*)src + 1;
    16. }
    17. }
    18. else
    19. {
    20. //后->前
    21. while (sz--)
    22. {
    23. *((char*)dest + sz) = *((char*)src+sz);
    24. /*dest = (char*)dest - 1;
    25. src = (char*)src - 1;*/
    26. }
    27. }
    28. return ret;
    29. }
    30. int main()
    31. {
    32. int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    33. int arr2[] = { 1,2,3,4,5,6,7,8,9,10 };
    34. my_memmove(arr1+2, arr1, 20);
    35. for (int i = 0; i < 10; i++)
    36. {
    37. printf("%d ", arr1[i]);
    38. }
    39. printf("\n");
    40. my_memmove(arr2 , arr2+2, 20);
    41. for (int j = 0; j < 10; j++)
    42. {
    43. printf("%d ", arr2[j]);
    44. }
    45. return 0;
    46. }

     这样我们的代码就能实现memmove的效果了

    3.memset

    3.1memset函数的使用

    void * memset ( void * ptr, int value, size_t num );

    memset函数是以字节为单位设置内存的函数 

    将 ptr 指向的内存块第1个字节(num)设置为指定(value)

    举个例子

    4.memcmp

    4.1memcpy函数的使用

    int memcmp ( const void * ptr1, const void * ptr2, size_t num );

    memcmp函数作用是比较ptr1和ptr2指向的内存空间的前num个字节的数据

    • 如果相同则返回0
    • 如果ptr1指向内存的数据是小于ptr2指向内存的数据的,则返回小于0的数字
    • 否则返回大于0的数字

    memcmp比较是以字节为单位比较的

    举个例子

     

  • 相关阅读:
    货币数字转换千分位,使用过滤器属性filters实现
    【100个 Unity实用技能】| C#中 Add 和 AddRange 的区别 及 使用示例
    Golang语言设计模式的实现—工厂模式
    实验三 蓝桥ROS1可视化和调试工具 适用kinetic/melodic/noetic
    关于 头歌平台 复制限制解除的方法
    数据库迁移-国产化-迁移建议-GreenPlum DB向GBase 8a 迁移
    Java调用Azure证书错误javax.net.ssl.SSLHandshakeException
    LeetBook新手村题单
    应试教育导致学生迷信标准答案惯性导致思维僵化-移动机器人
    Java实现微信支付
  • 原文地址:https://blog.csdn.net/m0_74722801/article/details/132892333