模拟实现字符串函数以及内存函数(均包含在头文件“string.h“中)

简介: ①不限字符个数型(strlen, strcpy, strcmp, strcat,strstr)②限字符个数型(strncpy, strcmp, strncat)③内存型(memcpy, memmove, memset)

目录:


①不限字符个数型(strlen, strcpy, strcmp, strcat,strstr)


②限字符个数型(strncpy, strcmp, strncat)


③内存型(memcpy, memmove, memset)


通过实现模拟,会更好的了解一些细节!


①限制个数的字符串函数


也就是不需要给个数,只要识别到 '\0' 字符就会停下。


②不限制就是多了个size_t的数字num,只会识别num个(感兴趣的可以自己去模拟哦!)


注意(如果num大于第二个字符串的大小,会自动补充 '\0' )(如果第一个字符串太小了,会越界访问!)


这是strlen函数(字符串长度)的模拟,(size_t)就是无符号整形


形参为指针(起始位置),然后到 '\0'停止计算,最终得到“长度”

size_t my_strlen(const char* str)
{
  unsigned int ret = 0;
  while (*str++)
  {
  ret++;
  }
  return ret;
}

这是strcpy函数(字符串拷贝)的模拟


形参为目的地指针(起始位置),源头指针(起始位置),最终返回目的地指针的起始位置


char* my_strcpy(char* str1, const char* str2)
{
  char* ret = str1;
  while (*str1++ = *str2++)
  {
  ;
  }
  return ret;
}

这是strcat函数(字符串延续)的模拟


形参为目的地指针(起始位置),源头指针(起始位置),最终返回目的地指针的起始位置


char* my_strcat(char* str1, const char* str2)
{
  char* ret = str1;
  while (*str1)
  {
  str1++;
  }
  while (*str1++ = *str2++)
  {
  ;
  }
  return ret;
}

这是strcmp函数(字符串比较)的模拟


形参为两个字符串的起始位置


(左大于右)返回大于0的数字,反之小于0的数字,相等则为0

int my_strcmp(const char* str1, const char* str2)
{
  while (*str1 == *str2 && *str1 != '\0')
  {
  str1++;
  str2++;
  }
  return *str1 - *str2;
}

这是strstr函数(字符串查找)的模拟


形参为两个指针,第二个是要查找的,如果在第一个字符串找到一模一样的,那么就返回这个相同字符串的首地址,找不到符号NULL

char* my_strstr(const char* str1, const char* str2)
{
  char* tmp = str2;
  char* ret = str1;
  while (*ret != '\0')
  {
  str1 = ret;
  str2 = tmp;
  while (*str1 == *str2)
  {
    str1++;
    str2++;
    if (*str2 == '\0')
    return ret;
  }
  ret++;
  }
  return NULL;
}
这里是实例:
int main()
{
  char str[50] = "xXXXasasas";
  char s[50] = "XXXX";
  char tmp[50] = "xXXXasasas";
  printf("%zd \n", my_strlen(str));
  printf("%s\n",  my_strcpy(str, s));
  my_strcpy(str, tmp);
  printf("%d\n", my_strcmp(str,s));
  my_strcpy(str, tmp);
  printf("%s\n", my_strcat(str, s));
  my_strcpy(str, tmp);
  printf("%p\n", my_strstr(str, s));
  printf("%s\n", my_strstr(str, s));
  printf("%s\n", my_strstr(str, "XXX"));
  return 0;
}


内存函数:


可以用于一切类型,因为它们的返回类型是void*,接受的也是void*,void*可以包容任何指针,但是使用的时候要强制类型转换!


当然,int*也可以,但是会报警告(指针跳过和指针访问都不一样了),


就是说传参的时候不匹配,有时候没事,有时候有事,


因为不匹配会直接使用定义函数时候的那个类型,这会导致我们不能获得想要的效果,甚至报错,因为设计函数的时候,一些细节被破坏,指针越界之类的....

//memcpy 解决不重叠问题
void* my_memcpy(void* des,const void* sou, size_t num)
{
  void* ret = des;
  char* pd = (char*)des;
  char* ps = (char*)sou;
  while (num--)
  {
  *pd++ = *ps++;
  }
  return ret;
}
//memmove 解决重叠问题
void* my_memmove(void* des, void* sou, size_t num)
{
  void* ret = des;
  char* pd = (char*)des;
  char* ps = (char*)sou;
  if (des < sou)
  {
  while (num--)
  {
    *pd++ = *ps++;
  }
  }
  else
  {
  pd = (char*)des + num - 1;
  ps = (char*)sou + num - 1;
  while (num--)
  {
    *pd-- = *ps--;
  }
  }
  return ret;
}

这里有个技巧,就是转化为char*就可以一个一个访问字节


还有,就是遇到重复型,要比较起始位置来确定如何交换


{


① 头到头


②尾到尾


}


最后,memset函数就是把int型数字截断成一个字节,然后按照num一个字节一个字节地“赋值”


//当然也可以是传入一个字符(刚好一个字节)


实例:

#include<string.h>
int main()
{
  int i = 0;
  int arr1[5] = { 1,2,3,4,5 };
  int arr2[5] = { 5,6,7,8,9 };
  int arr3[5] = { 1,2,3,4,5 };
  my_memcpy(arr1, arr2, 12);//返回值为void*,使用时强制类型转化。
  for (i = 0; i < 5; i++)
  {
  printf("%d ", arr1[i]);
  }
  my_memcpy(arr1, arr3, 20);
  my_memmove(arr1+2, arr1 , 12);
  for (i = 0; i < 5; i++)
  {
  printf("%d ", arr1[i]);
  }
  my_memcpy(arr1, arr3, 20);
  memset(arr1,257, 12);
  for (i = 0; i < 5; i++)
  {
  printf("%d ", arr1[i]);
  }
  my_memcpy(arr1, arr3, 20);
  memset(arr1, 1, 12);
  for (i = 0; i < 5; i++)
  {
  printf("%d ", arr1[i]);
  }
  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
|
1月前
|
Java
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
本文深入探讨了Java中方法参数的传递机制,包括值传递和引用传递的区别,以及String类对象的不可变性。通过详细讲解和示例代码,帮助读者理解参数传递的内部原理,并掌握在实际编程中正确处理参数传递的方法。关键词:Java, 方法参数传递, 值传递, 引用传递, String不可变性。
55 1
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性