字符串函数和内存函数的模拟实现
字符串函数
模拟实现strlen
strlen是求字符串长度函数
int my_strlen(const char* str)
{
int cnt = 0;//创建临时变量cnt
while (*str != '\0')//当str指向的空间不是\0时指针向后偏移,计数器加一
{
cnt++;
str++;
}
return cnt;//返回计数器的值
}
void test1()
{
char* p = "hello world!";
printf("%d ", my_strlen(p));
}
int main()
{
test1();
return 0;
}
模拟实现strcpy
strcpy是字符串拷贝函数
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest;
assert(dest != NULL);
assert(src != NULL);
while ((*dest++ = *src++))//这里表达式的结果就是src的值,如果遇到\0表达式为假,就会跳出循环
{
;
}
return ret;
}
void test2()
{
char* p = "hello world!";
char arr[20] = { 0 };
printf("%s ", my_strcpy(arr, p));
}
int main()
{
test2();
return 0;
}
模拟实现strcat
strcat是字符串追加函数,往目的地字符串后面追加一个字符串
char* my_strcat(char* dest, const char* src)
{
char* ret = dest;//保存起始地址作为返回值
assert(dest != NULL);
assert(src != NULL);//断言指针的有效性
while (*dest)//将目的地指针偏移到末尾\0的位置
{
dest++;
}
while ((*dest++ = *src++))//将之后的空间替换为src字符串的内容
{
;
}
return ret;
}
模拟实现strstr
strstr是字符串查找函数 在一个字符串中查找另一个字符串
这里分两种情况
实现思路
例如在abbbcdefg中查找bbc
1.创建cp变量储存第一个位置a的地址
2.循环遍历数组
3.如果找到 直接返回cp的地址 如果找不到cp++进行下一轮遍历
#include <stdio.h>
char* strstr(const char* str1, const char* str2)
{
char* cp = (char*)str1;//cp
char* s1, * s2;//创建临时变量记录每一轮遍历字符匹配
if (!*str2)//如果str2字符串为0 直接返回原字符串
return((char*)str1);
while (*cp)//cp没有指向字符串末尾\0时循环继续
{
s1 = cp;
s2 = (char*)str2;
while (*s1 && *s2 && !(*s1 - *s2))//s1指向的不是\0且s2指向的不是\0且s1=s2时循环继续
s1++, s2++;//跳到下一个字符继续匹配
if (!*s2)//如果s2为\0,也就是查找成功
return(cp);//返回起始位置cp的地址
cp++;//每轮循环结束cp++指向下个字符
}
return(NULL);//如果没有找到字符串 返回空指针
}
模拟实现strcmp
strcmp是字符比较函数
比较的是每个字符的ASCII值的大小
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
#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++;
}
/*if (*str1 > *str2)
return 1;
else
return -1;*/
return *str1 - *str2;
}
内存函数
模拟实现memcpy
memcpy是内存拷贝函数
void* my_memcpy(void* dst, const void* src, size_t count)
{
void* ret = dst;//ret记录起始位置地址
assert(dst);//断言指针的有效性
assert(src);
/*
* copy from lower addresses to higher addresses
*/
while (count--)//count是要拷贝字节的数量
{
*(char*)dst = *(char*)src;//将src指向的内容给dst
dst = (char*)dst + 1;
src = (char*)src + 1;//完成拷贝后 指针向后偏移
}
return(ret);//返回ret
}
模拟实现memmove
和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
如果源空间和目标空间出现重叠,就得使用memmove函数处理。
void* my_memmove(void* dst, const void* src, size_t count)
{
void* ret = dst;
if (dst <= src || (char*)dst >= ((char*)src + count)) //正向拷贝
{
while (count--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
}
else//反向拷贝
{
dst = (char*)dst + count - 1;
src = (char*)src + count - 1;
while (count--)
{
*(char*)dst = *(char*)src;
dst = (char*)dst - 1;
src = (char*)src - 1;
}
}
return(ret);
}