一、strlen(字符串有效长度)的模拟实现:
有三种方式:
1、计算器:
size_t my_strlen_1(const char* str)
{
int count = 0;
while (*str)
{
count++;
str++;
}
return count;
}
2、递归实现
//递归
size_t my_strlen_2(const char * str)
{
if (*str == '\0'){
return 0;
}
else{
return 1 + my_strlen_2(str + 1);
}
}
3、指针减指针
//指针-指针的方式
size_t my_strlen_3(const char *str)
{
const char *p = str;
while (*p){
p++;
}
return p - str;
}
二、模拟实现字符串拷贝(strcpy)
char *my_strcpy(char *dest, const char* src)
{
assert(dest && src);
char *ret = dest;
while (*dest = *src){
dest++;
src++;
}
return ret;
}
三、模拟实现字符串追加strcat
只需要把dest指针移动到末尾剩下的逻辑和strcpy一样
/*
三、模拟实现strcat
*/
char *my_strcat(char* dest, const char* src){
assert(dest&&src);
char *ret = dest;
while (*dest){
dest++;
}
while (*dest = *src){
dest++;
src++;
}
return ret;
}
四、模拟实现strcmp
/*
模拟实现strcmp
*/
int my_strcmp(const char * src, const char *dest){
int ret = 0;
assert(src != NULL);
assert(dest != NULL);
while (!(ret = *(unsigned char*)src - *(unsigned char*)dest) && *dest)
{
src++;
dest++;
}
if (ret > 0){
return 1;
}
if (ret < 0){
return -1;
}
return ret;
}
五、模拟实现memcpy
/*
模拟实现memcpy
*/
void * my_memcpy(void * dst, const void *src, size_t num)
{
assert(dst && src);
char *_dst = (char *)dst;
char *_src = (const char*)src;
while (num){
*_dst = *_src;
_src++;
_dst++;
num--;
}
}
但是memcpy不能处理内存重叠的拷贝
通过画图分析其实字符串拷贝总体可以分为两部分,从低3地址拷贝到高地址,这时候上面的memcpy的逻辑将不再满足要求,所以要模拟实现下memmove,在早期的版本的编译器中,memmove可以处理内存重叠的情况,但是memcpy不可以,在比较新的编译器中优化了memcopy,现在二者功能一样。
六、memmove的模拟实现
/*
模拟实现memmove
*/
void * my_memmove(void * dst, const void *src, size_t num)
{
assert(dst && src);
char *_dst = (char *)dst;
char *_src = (const char*)src;
if (_dst > _src && _dst < _src + num)
{
//从右往左拷贝
_dst = _dst + num - 1;
_src = _src + num - 1;
while (num){
*_dst = *_src;
_src--;
_dst--;
num--;
}
}
else{
//从左向右拷贝
while (num){
*_dst = *_src;
_src++;
_dst++;
num--;
}
}
return dst;
}