文章目录
前言
字符串操作函数是C语言中非常重要的函数,里面包括了指针的精华,同时对学习数据结构,如链表,数组,有非常好的练手方法。同时,知道内部实现,是基础中的基础。所以学习字符串操作函数是深入学C的必经之路。
my_strlen()的实现
关于my_strlen()函数想必大家已经很熟悉了,此函数用于获取字符串长度,并返回长度数值。
算法思想:用while循环逐个扫描每个字符,同时变量i自增+1;当扫描到结束符时,c[i]=0,自动跳出循环,此时i的值即为字符串长度。
接下来看看代码
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* str)//加const不可修改的字符指针,增加代码的可读性
{
int count = 0;
assert(str);//不要忘记断言
while (*str != '\0')//以\0为读取结束标志
{
count++;
str++;
}
return count;
}
int main()
{
char arr[] = "hello world!";
int len = my_strlen(arr);//调用函数
printf("%d\n", len);
return 0;
}
再提醒下大家的就是断言,要记得引头文件#include<assert.h>
my_strcpy()的实现
my_strcpy()函数是将后者字符串复制给前者字符串,内置两个参数,前者为指向数组的指针,后者可以是指向数组的指针,也可以是字符串常量。
上代码
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest, char* str)
{
char* ret = dest;
assert(dest && str)//一样的断言
while (*dest++ = *str++)
{
;
}
return ret;
}
int main()
{
char arr1[] = "hello world!";
char arr2[20] = { 0 };
my_strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
my_strcmp()的实现
my_strcmp()函数用于比较两个字符串大小,实质逐个比较每个字符的ASCII值。大于则返回1;等于则返回0;小于则返回0;若一直相等,则直到一方扫描结束为止。
上代码
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return *str1 - *str2;
}
int main()
{
char arr1[] = "hello world";
char arr2[] = "hello bit";
int ret = my_strcmp(arr1, arr2);
printf("%d\n", ret);
return 0;
}
my_strcat()的实现
my_strcat()函数是将两个字符串进行追加,目标字符串要包括’\0’,并且目标函数的大小一定要足够大,以保证源头字符串能够插入,同时源头字符串也同样要包括‘\0’。
实际上my_strcat()的原理大致是mystrlen()和my_strcpy()结合而来的。
为什么这么说呢?
因为:
1,逐个扫描前者字符串直到结束符位置,并记录结束符位置的下标(类似于mystrlen()函数的思想)
2,逐个扫描后者字符串,并逐个往前者字符串后面一次赋值,直到扫描到后者字符串结束符位置,最后给前者字符串加上结束符。(类似于mystrcpy()函数的思想)
上代码
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest, const char* str)
{
assert(dest && str);
char* ret = dest;
//找目标空间中的‘\0’
while (*dest != '\0')
{
dest++;
}
//拷贝
while (*dest++ = *str++)
{
;
}
return ret;
}
int main()
{
char arr1[20] = "hello ";
char arr2[] = "world!";
//追加
my_strcat(arr1, arr2);
printf("%s\n", arr1);
return 0;
}
my_strstr()的实现
my_strstr()函数是查找字符串的子串,找到后返回子串首元素之后的元素。
核心算法思想:
1、strstr() 函数搜索一个字符串在另一个字符串中的第一次出现。
2、找到所搜索的字符串,则该函数返回第一次匹配的字符串的地址;
3、如果未找到所搜索的字符串,则返回NULL。
上代码
#include<stdio.h>
char* my_strstr(const char* str1, const char* str2)
{
char* s1 = NULL;
char* s2 = NULL;
char* cp = str1;
while (*cp)
{
s1 = cp;
s2 = str2;
while (*s1 && *s2 && *s1 == *s2)
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return cp;
}
cp++;
}
return NULL;
}
int main()
{
char arr1[] = "hello world";
char arr2[] = "wor";
char* p = my_strstr(arr1, arr2);
if (p == NULL)
{
printf("找不到\n");
}
else
{
printf("%s\n", p);
}
return 0;
}
my_memcpy()的实现
主要针对两字符串无重叠的情况,这个也要根据编译器来决定,在(VS2019和VS2022)是可以实现有重叠的现象的。这里就不多解释,重点解释下一段代码喔
上代码
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
void* my_memcpy(void *dest, const void *src, size_t num)
{
void* ret = dest;
assert(dest && src);
while(num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = { 0 };
int sz = sizeof arr1 / sizeof arr1[0];
int len = sizeof(arr1);
int i = 0;
my_memcpy(arr2, arr1, len);
for (i = 0; i < sz; i++)
{
printf("%d ", arr2[i]);
}
printf("\n");
return 0;
}
my_memove()的实现
首先,使用memove进行重叠字符串的拷贝大致可分为两种情况:
1.从前向后拷贝:当src内存位置高于dest
2.从后向前拷贝:当src内存位置低于dest
上代码
#include<stdio.h>
#include<assert.h>
void my_memmove(void* dest, const void* src, size_t num)
{
void* ret = dest;
assert(dest && src);//确保不是空指针,用到指针都要想起这个
if (dest < src)//得分两种情况,前-->后
{
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else//后-->前
{
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
}
}
return ret;
}
void test()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
my_memmove(arr1 + 5, arr1, 20);//意思是,将arr1覆盖给arr1+5
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
}
int main()
{
test();
return 0;
}
总结:
当我们dest的地址小于src的地址时我们就采用从前向后拷贝
当我们dest的地址大于src但是小于src+count的地址我们采用的从后向前拷贝
当我们的dest大于src+count的地址的时候从前从后拷贝都可以
所以当我们模拟实现这个函数的时候
就把它分成两种情况而定dest<src和dest>=src这两种情况讨论就行了。
![在这里插入图片描述](https://img-blog.csdnimg.cn/7669cfad2e9f4d56bfdf38011e3bf03b.png
😍好啦,本次分享到这里就结束了,欢迎各位佬来指正小白做的不好的地方,感谢品读,持续关注喔