学C的第二十八天【字符串函数和内存函数的介绍(一)】-3

简介: 方法3:迭代方式

方法3:迭代方式


对应代码:

#include <stdio.h>
//方法3:迭代方式
size_t my_strlen(const char* str)
//和库函数的strlen函数一样
//返回值为无符号整型,参数为常量字符指针
{
  if (*str == '\0')
  {
    return 0;//如果第一个就指向\0,说明长度是0
  }
  else
  {
    return 1 + my_strlen(str + 1);
  }
}
int main()
{
  size_t sz = my_strlen("abc");
  //使用模拟实现的strlen函数返回一个size_t(无符号整数)的数
  //进行打印:
  printf("%u\n", sz);
  //%u:打印无符号的数
  return 0;
}

(2). 模拟实现strcpy()函数:

主函数:

189a0cefb1f54c52922cc4ac44f6fdcb.png

模拟实现strcpy()函数:

image.png

对应代码:

//模拟strcpy函数:
#include <stdio.h>
#include <assert.h>
char* my_strcpy(char* dest, const char* src)
//返回值类型 和 参数 与库函数strcpy相同
//返回值设置为char*,是为了能够使用链式访问,把返回值作为其它函数的参数
{
  //保存目标空间指针原位置,方便最后进行返回
  char* ret = dest;
  //进行断言,两个指针都不为空指针,需要头文件<assert.h>
  assert(dest != NULL);
  assert(src != NULL);
  //只要 源字符串 还没指向 \0 就继续循环拷贝
  while (*src != '\0')
  {
    *dest = *src; //将源字符串的一位赋给目标空间
    //下次赋值下一位,所以要移动两个指针:
    dest++;
    src++;
  }
  //循环中没有将 \0 赋给目标空间,所以要加上:
  *dest = *src;
  //循环完后,dest移向了新位置,src在\0位置,所以直接赋值即可
  //返回拷贝后的目标指针原地址:
  return ret;
}
int main()
{
  //目标空间(字符数组):
  char arr1[20] = "xxxxxxxxxxxxxxxx";
  //源字符串:
  char arr2[] = "hello world";
  my_strcpy(arr1, arr2); //使用模拟的函数来拷贝
  //arr1为目标空间指针,arr2为源字符串指针
  //将arr2指向的内容 拷贝到 目标空间指针中
  //打印拷贝结果:
  printf("%s\n", arr1);
  return 0;
}

可进行化简:

image.png

对应代码:

//模拟strcpy函数:
#include <stdio.h>
#include <assert.h>
char* my_strcpy(char* dest, const char* src)
//返回值类型 和 参数 与库函数strcpy相同
//返回值设置为char*,是为了能够使用链式访问,把返回值作为其它函数的参数
{
  //保存目标空间指针原位置,方便最后进行返回
  char* ret = dest;
  //进行断言,两个指针都不为空指针,需要头文件<assert.h>
  assert(dest != NULL);
  assert(src != NULL);
  //只要 源字符串 还没指向 \0 就继续循环拷贝
  while (*dest++ = *src++)
  {
    ;
  }
  //返回拷贝后的目标指针原地址:
  return ret;
}
int main()
{
  //目标空间(字符数组):
  char arr1[20] = "xxxxxxxxxxxxxxxx";
  //源字符串:
  char arr2[] = "hello world";
  my_strcpy(arr1, arr2); //使用模拟的函数来拷贝
  //arr1为目标空间指针,arr2为源字符串指针
  //将arr2指向的内容 拷贝到 目标空间指针中
  //打印拷贝结果:
  printf("%s\n", arr1);
  return 0;
}

(3). 模拟实现strcat()函数:

image.png

对应代码:

//模拟strcat函数:
#include <stdio.h>
#include <string.h>
#include <assert.h>
char* my_strcat(char* dest, const char* src)
{
  //进行断言,两个字符串都不为\0 (空)
  assert(dest);
  assert(src);
  //保存目标地址的原位置
  char* ret = dest;
  //找到目标字符串的\0,作为连接的起点:
  while (*dest)
  {
    dest++;
  }
  //开始连接字符串,和strcpy是一样的
  while (*dest++ = *src++)
  {
    ;
  }
  //返回连接后的目标空间指针:
  return ret;
}
int main()
{
  //目标空间(数组):
  char arr1[20] = "hello";
  //源字符串:
  char arr2[] = " world";
  //使用模拟的自定义函数,将arr2连接到arr1后
  my_strcat(arr1, arr2);
  //打印连接后的新字符串:
  printf("%s\n", arr1);
  return 0;
}

(4). 模拟实现strcmp()函数:

7e921d29b5694c7bb49ecb3e6b2cf6a4.png

对应代码:

//模拟strcmp函数:
#include <stdio.h>
int my_strcmp(const char* str1, const char* str2)
{
  while (*str1 == *str2)
    //两字符串同位置上的值相同的情况
  {
    if (*str1 == '\0')
      //同位置上都是\0说明两个字符串相同
    {
      return 0; //相同则返回 0
    }
    //不是\0,是其它值相同,则判断下一位
    str1++;
    str2++;
  }
  if (*str1 > *str2)
    //当前位置,字符串1的字符大于字符串的字符
  {
    return 1; //大于则返回大于0的数
  }
  else
    //当前位置,字符串1的字符小于字符串的字符
  {
    return -1; //小于则返回小于0的数
  }
}
int main()
{
  //使用自定义函数进行比较:
  int ret = my_strcmp("abq", "abc");
  printf("%d\n", ret);
  return 0;
}


(5). 模拟实现strstr()函数:

模拟的自定义函数:

image.png

主函数:

image.png

对应代码:

//模拟strncmp函数:
#include <stdio.h>
#include <string.h>
char* my_strstr(char* str1, char* str2)
{
  char* cp = str1; //开始进行判断的初始位置指针
  char* s1 = cp; //在arr1中的cp位置开始逐位进行匹配的指针
  char* s2 = str2; //在arr2中逐位进行匹配的指针
  //如果要找的子字符串为空指针,则返回str1:
  if (*str2 == '\0')
  {
    return str1;
  }
  while (*cp != '\0')
    // \0之后不可能找到arr2的内容
  {
    //开始匹配:
    s1 = cp; //让s1在初始位置开始进行逐位判断
    s2 = str2;
    while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
      //两字符串都未到\0,如果当前位置的内容相同,则再循环判断下一位
    {
      s1++;
      s2++;
    }
    if (*s2 == '\0')
      //如果子字符串已经到了\0,
      //说明arr1中有arr2,匹配成功
    {
      return cp; 
      //匹配成功,则返回子字符串的初始位置
    }
    cp++; //判断arr1下一个初始位置
  }
  return NULL; //未找到则返回空指针
}
int main()
{
  char arr1[] = "abbbcdef";
  char arr2[] = "bbc";
  //使用自定义函数进行查找:
  char* ret = my_strstr(arr1, arr2);
  if (ret != NULL)
  {
    printf("%s\n", ret);
  }
  else
  {
    printf("未找到");
  }
  return 0;
}


相关文章
|
1月前
|
C语言 C++
C语言 之 内存函数
C语言 之 内存函数
34 3
|
29天前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
1月前
|
存储 程序员 编译器
C语言——动态内存管理与内存操作函数
C语言——动态内存管理与内存操作函数
|
1月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
161 1
|
1月前
|
程序员 C语言
C语言内存函数精讲
C语言内存函数精讲
|
25天前
|
存储 C语言
【c语言】字符串函数和内存函数
本文介绍了C语言中常用的字符串函数和内存函数,包括`strlen`、`strcpy`、`strcat`、`strcmp`、`strstr`、`strncpy`、`strncat`、`strncmp`、`strtok`、`memcpy`、`memmove`和`memset`等函数的使用方法及模拟实现。文章详细讲解了每个函数的功能、参数、返回值,并提供了具体的代码示例,帮助读者更好地理解和掌握这些函数的应用。
21 0
|
1月前
|
C语言 C++
c语言回顾-内存操作函数
c语言回顾-内存操作函数
40 0
|
1月前
|
存储 C语言 C++
来不及哀悼了,接下来上场的是C语言内存函数memcpy,memmove,memset,memcmp
本文详细介绍了C语言中的四个内存操作函数:memcpy用于无重叠复制,memmove处理重叠内存,memset用于填充特定值,memcmp用于内存区域比较。通过实例展示了它们的用法和注意事项。
66 0
|
1月前
一刻也没有为它哀悼~接下来登场的是动态内存分配的malloc与realloc以及free函数
一刻也没有为它哀悼~接下来登场的是动态内存分配的malloc与realloc以及free函数
67 0
|
3月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
376 0