• 模拟实现库函数,strtsr,memmove.


    <1>主页:C语言的前男友

    <2>知识讲解:模拟实现 库函数 strstr,memmove

    <3>创作者:C语言的前男友

    <4>开发环境:Visual Studio 2022

    <5>前言:学习了strstr,memnove等库里面的内存相关的函数,功能非常的强大。今天我们来模拟实现一下。

     

    目录

    一.strtsr()

    (1)strtsr介绍:

      (2)使用演示

    (3)模拟实现:

    (4) 代码:

    (5)代码效果:

     二.memmove()

    (1)memmove介绍

    (2)memmove演示:

    1.空间不重叠拷贝

    2.空间重叠的拷贝

    (3)模拟实现memmove

    (4)代码:

    (5)运行效果:

    最后:

    因为心中有梦,所以暗里有光,遥遥无期,那又怎样,踮起脚尖,就更接近阳光。


    一.strtsr()

    (1)strtsr介绍:

     strstr函数是库里面提供的查找字串的的一个函数,返回值是一个char*的指针,指针指向的是子串在原串中的位置指针,如果没有查找到的话,就会返回NULL。

    (2)使用演示

    1. #include
    2. #include
    3. int main()
    4. {
    5. char str1[] = "abcdefghij";
    6. char* str2 = "cde";
    7. char* str3 = "abp";
    8. //返回str2在str1中的位置指针,即返回"cdefhij";首元素的指针
    9. char* rep = strstr(str1, str2);
    10. char *rep1 = strstr(str1, str3);
    11. if (rep == NULL)
    12. {
    13. printf("没找到str2\n");
    14. }
    15. else
    16. {
    17. printf("找到了str2:%s\n",rep);
    18. }
    19. if (rep1 == NULL)
    20. {
    21. printf("没找到str3\n");
    22. }
    23. else
    24. {
    25. printf("找到了str2%s\n", rep1);
    26. }
    27. return 0;
    28. }

     (3)模拟实现:

     主要实现思路就是,从p指针位置,s1开始和s2匹配,如果 s1 和 s2 指向的字符相同,那就s1和s2都挪向下一个字符,如果s1和s2指向的字符不相同,那就意味着此次匹配失败,后面也就没有必要经行匹配了,直接 p 向后挪一个字符,进入下一次的匹配。直到s2指针 ‘ \0 ’ 时。匹配成功结束,或者 s1 也指向 ‘ \0 ’ 了,原串都匹配玩了,自然也就结束了。

    (4) 代码:

    1. char* my_strstr(char* str1, char* str2)
    2. {
    3. char* p = str1;
    4. while (*p)
    5. {
    6. char* s1 = p;
    7. char* s2 = str2;
    8. //从p的位置开始与s1 和 s2 开始匹配。
    9. while (*s2 != '\0' && *s1 != '\0' && *s1 == *s2)
    10. {
    11. s1++;
    12. s2++;
    13. }
    14. //当匹配出来时,只有s2 已经指向‘ \0 ’,才说明匹配成功
    15. if (*s2 == '\0')
    16. {
    17. return p;
    18. }
    19. p++;
    20. }
    21. //当原串都匹配完了,那就是没有原串中没有子串,返回NULL;
    22. return NULL;
    23. }

    (5)代码效果:

     二.memmove()

    (1)memmove介绍

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

    memmove是将,source 后面的 num 个字节的数据,拷贝到 destination 处,而且源内存块和目标内存块重叠也是可以处理的。

    (2)memmove演示:

    1.空间不重叠拷贝

    1. #include
    2. #include
    3. #include
    4. void print(int* arr, int n)
    5. {
    6. for (int i = 0; i < n; i++)
    7. {
    8. printf("%d ", arr[i]);
    9. }
    10. printf("\n");
    11. }
    12. int main()
    13. {
    14. int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    15. int arr2[10] = { 0 };
    16. print(arr2, 10);
    17. //将arr1中的前 4 * 5 = 20 个字节拷贝到arr2中,
    18. memmove(arr2, arr1, 20);
    19. print(arr2, 10);
    20. return 0;
    21. }

    2.空间重叠的拷贝

    1. #include
    2. #include
    3. #include
    4. void print(int* arr, int n)
    5. {
    6. for (int i = 0; i < n; i++)
    7. {
    8. printf("%d ", arr[i]);
    9. }
    10. printf("\n");
    11. }
    12. int main()
    13. {
    14. int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
    15. int arr2[10] = { 0 };
    16. print(arr1, 10);
    17. //将arr1后面的20个字节,拷贝到 arr1+2 后面20字节
    18. //arr1后面的20个字节就是 1 2 3 4 5
    19. //arr1+2后面20个字节就是 3 4 5 6 7
    20. memmove(arr1+2, arr1, 20);
    21. print(arr1, 10);
    22. return 0;
    23. }

    (3)模拟实现memmove

    首先memmove就是具有,对重叠空间的处理能力的。所以我们在模拟实现之前就要弄清楚,重叠空间拷贝时会有那些意想不到的结果。

    所以:

    当我们是将后面的间的内容拷贝到前面的空间时,就需要从前往后拷贝。

    当我们是将前面空间的内容拷贝到后面的空间时,就需要从后往前拷贝。

    (4)代码:

    1. #include
    2. #include
    3. #include
    4. void print(int* arr, int n)
    5. {
    6. for (int i = 0; i < n; i++)
    7. {
    8. printf("%d ", arr[i]);
    9. }
    10. printf("\n");
    11. }
    12. //参数设计:dest->目标空间 source->原数据空间 num->拷贝大小(单位:字节);
    13. void* my_memmove(void*dest,const void*source,size_t num)
    14. {
    15. void* ret = dest;
    16. assert(dest && source);
    17. //如果目标的空间在原数据的前面,那就从前往后拷贝。
    18. if (dest < source)
    19. {
    20. while (num--)
    21. {
    22. *((char*)dest) = *((char*)source);
    23. dest = (char*)dest + 1;
    24. source = (char*)source + 1;
    25. }
    26. }
    27. //如果目标空间在原数据的后面,那么就从后往前拷贝。
    28. else
    29. {
    30. while (num--)
    31. {
    32. *((char*)dest + num) = *((char*)source + num);
    33. }
    34. }
    35. return ret;
    36. }
    37. int main()
    38. {
    39. int arr[] = {1,2,3,4,5,6,7,8,9,10};
    40. print(arr, 10);
    41. my_memmove(arr , arr+2, 20);
    42. print(arr, 10);
    43. }

    (5)运行效果:

    最后:

    因为心中有梦,所以暗里有光,遥遥无期,那又怎样,踮起脚尖,就更接近阳光。

  • 相关阅读:
    【Java】Groovy 语言应用场景以及积累
    单调队列优化DP
    【Linux】环境基础开发工具使用
    SQL sever中的存储过程
    GPE(Grafana+Prometheus+Exporter)项目实战之Golang篇(上)
    python中pdf转图片的操作方法二
    第58章 结构、纪录与类
    金字塔思维
    高效查找对标账视频号
    mysql Lock wait timeout exceeded; try restarting transaction解决方案
  • 原文地址:https://blog.csdn.net/qq_63943454/article/details/126839565