• 库函数的模拟实现


    前言:

    在上一篇文章中我们了解到了一些库函数的使用,为了加深我们对库函数的理解,我们来模拟实现一下这些库函数的用法。

    这是上一篇文章的链接:

    http://t.csdnimg.cn/r7SKNicon-default.png?t=N7T8http://t.csdnimg.cn/r7SKN

    1.模拟实现strlen

    模拟实现strlen函数有三种基本方式:

    方式1:计数器方式

    1. #include
    2. int my_strlen(const char* str)
    3. {
    4. int count = 0;
    5. while (*str)
    6. {
    7. count++;
    8. str++;
    9. }
    10. return count;
    11. }

    方式2:不能创建临时变量计数器

    1. #include
    2. int my_strlen(const char* str)
    3. {
    4. if (*str == '\0')
    5. return 0;
    6. else
    7. return 1 + my_strlen(str + 1);
    8. }

    方式3:指针-指针的方式

    1. #include
    2. int my_strlen(char* s)
    3. {
    4. char* p = s;
    5. while (*p != ‘\0’)
    6. p++;
    7. return p - s;
    8. }

    2.模拟实现strcpy

    1. #include
    2. #include
    3. char* my_strcpy(char* dest,const char* src)
    4. {
    5. char* ret = dest;
    6. assert(dest && src);
    7. while (*dest++ = *src++)
    8. {
    9. ;
    10. }
    11. return ret;
    12. }
    13. int main()
    14. {
    15. char arr1[20] = { 0 };
    16. char arr2[] = "abc";
    17. my_strcpy(arr1, arr2);
    18. printf("%s\n", arr1);
    19. return 0;
    20. }

    my_strcpy这个函数的返回值是char*,参数是两个char*的指针,但是第二个参数也就是源字符串是不需要改动的,所以加上const限制一下。

    首先我们用while循环,将*src找到的字符存放到*dest里面去,只要这个字符不是\0,这个循环就还是会执行,然后使用后置++,跳过一个字符。我们在进入while循环之前使用assert进行断言一下,保证dest和src不为NULL。

    strcpy在库函数里面的规定的返回值是目标空间的起始地址,所以先用char*的指针保存一下dest的起始地址,最后返回ret。

    3 模拟实现strcat

    1. #include
    2. #include
    3. char* my_strcat(char* dest,const char* src)
    4. {
    5. char* ret = dest;
    6. assert(dest && src);
    7. while(*dest != '\0')
    8. {
    9. *dest++;
    10. }
    11. while (*dest++ = *src++)
    12. {
    13. ;
    14. }
    15. return ret;
    16. }
    17. int main()
    18. {
    19. char arr1[20] = "abc";
    20. char arr2[] = "def";
    21. my_strcat(arr1, arr2);
    22. printf("%s\n", arr1);
    23. return 0;
    24. }

    第一步我们先找到目标空间的末尾,也就是找到\0,第二步进行数据追加。
     用第一个while循环找到目标空间的末尾,再用第二个while循环进行数据追加,追加的过程和strcpy是一样的。

     4 模拟实现strcmp

    1. #include
    2. #include
    3. int my_strcmp(const char* str1, const char* str2)
    4. {
    5. assert(str1 && str2);
    6. while (*str1 == *str2)
    7. {
    8. str1++;
    9. str2++;
    10. }
    11. if (*str1 > *str2)
    12. return 1;
    13. else
    14. return -1;
    15. }
    16. int main()
    17. {
    18. char arr1[] = "abz";
    19. char arr2[] = "abq";
    20. if (my_strcmp(arr1, arr2) > 0)
    21. {
    22. printf(">\n");
    23. }
    24. else
    25. {
    26. printf("<=\n");
    27. }
    28. return 0;
    29. }

    库函数strcmp的返回值是0,<0,>0,所以返回值为int,因为两个参数都不需要修改,所以使用const限制一下,再用assert断言一下。先写一个while函数判断字符是否相同,相同则++进行下一个字符的比较,如果不相同则进入if,判断是>还是<,>则返回1,否则返回-1。

    5.模拟实现strstr

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include
    3. #include
    4. const char* my_strstr(const char* str1, const char* str2)
    5. {
    6. const char* cp;//记录开始匹配的位置
    7. const char* s1;//遍历str1指向的字符串
    8. const char* s2;//遍历str2指向的字符串
    9. assert(str1 && str2);
    10. if (*str2 == '\0')
    11. return str1;
    12. cp = str1;
    13. while (*cp)
    14. {
    15. s1 = cp;
    16. s2 = str2;
    17. while (*s1 && *s2 && *s1 == *s2)
    18. {
    19. s1++;
    20. s2++;
    21. }
    22. if (*s2 == '\0')
    23. return cp;
    24. cp++;
    25. }
    26. return NULL;
    27. }
    28. int main()
    29. {
    30. char arr1[] = "abbbcdef";
    31. char arr2[] = "bbc";
    32. const char* ret = my_strstr(arr1, arr2);
    33. if (ret == NULL)
    34. {
    35. printf("找不到\n");
    36. }
    37. else
    38. {
    39. printf("%s\n", ret);
    40. }
    41. return 0;
    42. }

    首先我们创建一个指针cp,让cp记录开始匹配的位置。再创建一个指针s1,遍历str1指向的字符串。再创建一个指针s2,遍历str2指向的字符串。所以cp一开始指向的就是str1的起始位置,所以使用while循环,如果str1是NIULL就不用找了,直接返回NULL。如果不是空指针,则进入循环,将cp赋给s1,str2赋给s2。再使用一个while循环,如果*s1和*s2都不为空指针且*s1==*s2的话则进入while循环,然后s1++,s2++,判断下一个字符是否相等,如果出现了不相等的情况,则cp++,从str1的下一个字符开始判断。用if判断如果s2++出现了等于\0的情况,那么就是全部找到了,这个时候就返回cp就行了。当s1为\0的时候也是返回NUL的。


    今天的分享到这里就结束啦!谢谢老铁们的阅读,让我们下期再见。 

  • 相关阅读:
    如何每天自动发送心灵鸡汤、正能量语录
    Ceph提供nfs服务
    【操作系统】内存管理
    2015架构真题(五十)
    Django中使用Celery和APScheduler实现定时任务
    编码转换 C#
    kubernetes使用glusterfs
    深夜学习:有关Inner、Outer等相关词汇的理解
    Python类的多种方法,你分得清吗?
    【统计分析数学模型】聚类分析: 系统聚类法
  • 原文地址:https://blog.csdn.net/2301_79035870/article/details/133434949