前言
心向秃又强!!!
目录
strlen函数
分析:
1, 统计字符串的长度, "\0"为唯一结束标记, 要注意防止越界;
2, 形参为字符指针;
3, 返回值为size_t, 无符号整形;
4, 对其断言assert, 防止传过来空指针;
实现: 三种实现方式
//模拟实现strlen
//方法一: 普通循环实现
size_t my_strlen1(char* str)
{
int count = 0;
assert(str); //头文件为<assert.h>
while (*str++)
{
count++;
}
return count;
}
//方法二: 递归实现
size_t my_strlen2(char* str)
{
if (!*str)
return 0;
else
return 1 + my_strlen2(str + 1);//注意这里不能用++,因为递归还要退栈,所以指针str不能改变指向,
}
//方法三: 指针 - 指针
size_t my_strlen3(char* str)
{
char* p = str;
while (*p) //这里使用后置++的话,会多循环一次, 至于为什么, 看我博客 while循环后置++的判断细节
{
p++;
}
return p - str;
}
int main()
{
char arr[] = { "abcdef" };
printf("%d", my_strlen3(arr));
return 0;
}
strcpy函数
分析:
1, 拷贝字符串, 参数为两个指针, (char* dest, const char* str), 第一个指向目标字符串, 第二个指向源字符串;
2, 注意参数顺序, 将str空间的字符拷贝到dest中, 这里const修饰指针str指向的内容,是不希望其指向的内容被修改; 保证代码的健壮性.
3, 循环拷贝, 以str指向\0为结束条件, 需要注意的是, \0也要拷贝到dest当中去, 使用while循环,就可以考虑在判断条件中使用后置++;
4, 函数的返回值为char* , 并且是目标空间dest的起始指针, 所以需要在一开始,保存起始指针;
实现:
//strcpy库函数的模拟实现
char* my_strcpy(char* dest, const char* str)
{
char* ret = dest;
assert(dest && str);
while (*dest++ = *str++)
{
;
}
return ret;
}
int main()
{
char arr1[10] = { "abcdef" };
char arr2[10] = { 0 };
printf("%s", my_strcpy(arr2, arr1));
return 0;
}
strcat函数
分析:
1, 追加字符串, 参数为两个指针, 第一个指向目标字符串, 第二个指向源字符串, 考虑const修饰;
2, 返回值为 目标空间的起始地址, 需要在一开始就保存起始地址;
3, assert断言 保证用户没有传递空指针;
4, 需要先找到目标字符串的末位\0, 再追加字符串, 需要保证目标空间足够大;
5, 也会将源字符串中的\0追加过去;
实现:
//strcat函数的模拟实现
char* my_strcat(char* dest, const char* str)
{
char* ret = dest;
assert(dest && str);
while (*dest)
{
dest++;
}
while (*dest++ = *str++)
{
;
}
return ret;
}
int main()
{
char arr1[10] = { "abcdef" };
char arr2[20] = { "acb"};
printf("%s", my_strcat(arr2, arr1));
return 0;
}
strcmp函数
分析:
1, 比较的是字符串的ASCLL值, 而不是长度;
2, 参数为两个指针, 分别指向两个字符串, 考虑用const修饰指针;
3, 返回值为 大于0的数/ 0/ 小于0的数, 这里我们设置为1/ 0/ -1;
4, 断言assert, 防止用户传递空指针;
实现:
//strcmp函数模拟实现
int my_strcmp(const char* str1, const char* str2)
{
int ret = 0;
assert(str1 && str2);
while (!(ret = *str1 - *str2) && *str1 && *str2)
{
str1++;
str2++;
}
if (ret < 0)
ret = -1;
else if (ret > 0)
ret = 1;
return ret;
}
int main()
{
char arr1[10] = { "abcdef" };
char arr2[20] = { "aab" };
int ret = my_strcmp(arr1, arr2);
printf("%d \n", ret);
return 0;
}
strstr函数
分析:
1, 查找子字符串, 需要保留每一次查找的初始位置, 以保证在字符串不同时,可以回到查找的起始位置, 从下一个字符继续查找;
2, 两个指针, 分别指向不同的字符, 考虑使用const修饰指针;
3, 若传递的子字符串的指针为空, 返回目标字符串的指针;
4, 未找到则返回NULL;
实现:
//strstr函数模拟实现
char* my_strstr(const char* str1, const char* str2)
{
char* cp = str1;
char* s1, * s2;
if (!*str2)
return (char*)str1;
while (*cp)
{
s1 = cp;
s2 = (char*)str2;
while (*s1 && s2 && !(*s1 - *s2))
{
s1++;
s2++;
}
if (!*s2)
return cp;
cp++;
}
return (NULL);
}
int main()
{
char arr1[10] = { "abcdef" };
char arr2[20] = { "def" };
printf("%s\n",my_strstr(arr1, arr2));
return 0;
}
我是专注学习的章鱼哥~