<1>主页:C语言的前男友
<2>知识讲解:模拟实现 库函数 strstr,memmove
<3>创作者:C语言的前男友
<4>开发环境:Visual Studio 2022
<5>前言:学习了strstr,memnove等库里面的内存相关的函数,功能非常的强大。今天我们来模拟实现一下。

目录
因为心中有梦,所以暗里有光,遥遥无期,那又怎样,踮起脚尖,就更接近阳光。
strstr函数是库里面提供的查找字串的的一个函数,返回值是一个char*的指针,指针指向的是子串在原串中的位置指针,如果没有查找到的话,就会返回NULL。
- #include
- #include
- int main()
- {
- char str1[] = "abcdefghij";
- char* str2 = "cde";
- char* str3 = "abp";
- //返回str2在str1中的位置指针,即返回"cdefhij";首元素的指针
- char* rep = strstr(str1, str2);
- char *rep1 = strstr(str1, str3);
- if (rep == NULL)
- {
- printf("没找到str2\n");
- }
- else
- {
- printf("找到了str2:%s\n",rep);
- }
- if (rep1 == NULL)
- {
- printf("没找到str3\n");
- }
- else
- {
- printf("找到了str2%s\n", rep1);
- }
- return 0;
- }
主要实现思路就是,从p指针位置,s1开始和s2匹配,如果 s1 和 s2 指向的字符相同,那就s1和s2都挪向下一个字符,如果s1和s2指向的字符不相同,那就意味着此次匹配失败,后面也就没有必要经行匹配了,直接 p 向后挪一个字符,进入下一次的匹配。直到s2指针 ‘ \0 ’ 时。匹配成功结束,或者 s1 也指向 ‘ \0 ’ 了,原串都匹配玩了,自然也就结束了。
- char* my_strstr(char* str1, char* str2)
- {
- char* p = str1;
- while (*p)
- {
- char* s1 = p;
- char* s2 = str2;
- //从p的位置开始与s1 和 s2 开始匹配。
- while (*s2 != '\0' && *s1 != '\0' && *s1 == *s2)
- {
- s1++;
- s2++;
- }
- //当匹配出来时,只有s2 已经指向‘ \0 ’,才说明匹配成功
- if (*s2 == '\0')
- {
- return p;
- }
- p++;
- }
- //当原串都匹配完了,那就是没有原串中没有子串,返回NULL;
- return NULL;
- }
void * memmove ( void * destination, const void * source, size_t num );
memmove是将,source 后面的 num 个字节的数据,拷贝到 destination 处,而且源内存块和目标内存块重叠也是可以处理的。
- #include
- #include
- #include
- void print(int* arr, int n)
- {
- for (int i = 0; i < n; i++)
- {
- printf("%d ", arr[i]);
- }
- printf("\n");
- }
- int main()
- {
- int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
- int arr2[10] = { 0 };
-
- print(arr2, 10);
- //将arr1中的前 4 * 5 = 20 个字节拷贝到arr2中,
- memmove(arr2, arr1, 20);
- print(arr2, 10);
-
- return 0;
- }
- #include
- #include
- #include
- void print(int* arr, int n)
- {
- for (int i = 0; i < n; i++)
- {
- printf("%d ", arr[i]);
- }
- printf("\n");
- }
- int main()
- {
- int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
- int arr2[10] = { 0 };
-
- print(arr1, 10);
- //将arr1后面的20个字节,拷贝到 arr1+2 后面20字节
- //arr1后面的20个字节就是 1 2 3 4 5
- //arr1+2后面20个字节就是 3 4 5 6 7
- memmove(arr1+2, arr1, 20);
- print(arr1, 10);
-
- return 0;
- }
首先memmove就是具有,对重叠空间的处理能力的。所以我们在模拟实现之前就要弄清楚,重叠空间拷贝时会有那些意想不到的结果。
所以:
当我们是将后面的间的内容拷贝到前面的空间时,就需要从前往后拷贝。
当我们是将前面空间的内容拷贝到后面的空间时,就需要从后往前拷贝。
- #include
- #include
- #include
- void print(int* arr, int n)
- {
- for (int i = 0; i < n; i++)
- {
- printf("%d ", arr[i]);
- }
- printf("\n");
- }
- //参数设计:dest->目标空间 source->原数据空间 num->拷贝大小(单位:字节);
- void* my_memmove(void*dest,const void*source,size_t num)
- {
- void* ret = dest;
- assert(dest && source);
- //如果目标的空间在原数据的前面,那就从前往后拷贝。
- if (dest < source)
- {
- while (num--)
- {
- *((char*)dest) = *((char*)source);
- dest = (char*)dest + 1;
- source = (char*)source + 1;
- }
- }
- //如果目标空间在原数据的后面,那么就从后往前拷贝。
- else
- {
- while (num--)
- {
- *((char*)dest + num) = *((char*)source + num);
- }
- }
- return ret;
- }
- int main()
- {
- int arr[] = {1,2,3,4,5,6,7,8,9,10};
- print(arr, 10);
- my_memmove(arr , arr+2, 20);
- print(arr, 10);
- }
