常用库函数的模拟实现

模拟实现常见库函数

  •  strlen(字符串长度)
size_t strlen (const char* str);

strlen以'\0'为结束标志

函数返回的是在'\0'前面出现的字符的个数

函数的返回类型是size_t(无符号整形)

//计数器方式
int my_strlen(const char* str)
{
    int count = 0;
    assert(str != NULL);
    while(*str++ != '\0')
    {
        count++;
    }
    return count;
}

//递归实现
int my_strlen(const char* str)
{
    if(*str == '\0')
    {
        return 0;
    }
    else
    {
        return 1+my_strlen(str+1);
    }
}

//指针实现
int my_strlen(char* s)
{
    char* p = s;
    while(*p != '\0')
    {
        p++;
    }
    return p-s;
}

  •  strcpy(字符串拷贝)
char* strcpy(char* des, const char* str);

源字符串必须以'\0'结束

会将源字符串的'\0'拷贝到目标字符串

目标字符串空间必须足够大,必须可变

char* my_strcpy(char* des,const char* str)
{
    char* ret = des;
    assert(des != NULL);
    assert(str != NULL);
    while(*des++ = *str++)
    {
        ;
    }
    return ret;
}
  •  strncpy
char* strncpy(char* des, const char* str, size_t num);

拷贝num个字符到目标空间

如果源字符串长度小于num,拷贝完源字符串后,在目标函数后边追加0,直到num个

char* my_strncpy(char* dest, const char* src, size_t num)
{
    char* ret = dest;
    assert(dest != NULL);
    assert(src != NULL);
    while (num--)
	{
		if (*src != '\0')
		{
			*dest = *src;
			dest++;
			src++;
		}
		else
		{
			*dest = 0;
			dest++;
		}
	}
	return ret;
}

  •  strcat(字符串追加)
char* strcat(char* dest, const char* str);

源字符串必须以'\0'结束

目标空间足够大,可修改

字符串不能自己追加自己,不然无'\0'会一直追加下去

char* my_strcat(char* dest, const char* str)
{
    char* ret = dest;
    assert(dest != NULL);
    assert(str != NULL);
    //找到目标空间的'\0'
    while(*dest)
    {
        dest++;
    }
    //拷贝
    while(*dest++ = *str++)
    {
        ;
    }
    return ret;
}
  •  strncat
char* strncat(char* dest, const char* str, size_t num);

将源字符串的第一个num字符追加到目标字符串,并添加一个终止的'\0'

如果源文件中字符串的长度小于num,则只复制到'\0'之前的内容

char* my_strncat(char* dest, const char* str, size_t num)
{
    char* ret = dest;
    assert(dest != NULL);
    assert(str != NULL);
    while(*dest++)
    ;
    while(num--)
    {
        *dest++ = *str++;
    }
    return ret;
}
  •  strcmp(字符串比较)
int strcmp(const char* str1, const char*str2);

第一个不相等出现,哪个大就是哪个

str1>str2,返回大于0的数字

str1=str2,返回0

str1<str2,返回小于0的数字

int my_strcmp(const char* str1, const char*str2)
{
    assert(str1 != NULL);
    assert(str2 != NULL);
    while(*str1 == *str2)
    {
        if(*str1 == '\0')
        {
            return 0;
        }
        str1++;
        str2++;
    }
    return *str1 - *str2;
}
  •  strncmp
int strncmp(const char* str1, const char*str2, size_t num);

比较到出现两个字符不一样,或者一个字符串结束,或者num个字符全部比较完

int my_strncmp(const char* dest,const char* src,size_t num)
{
	int ret = 0;

	while (num--)
	{
		if (src == '\0')
			return 0;
		if (!(*dest == *src))
		{
			ret = *(unsigned char*)dest - *(unsigned char*)src;
		}
		dest++;
		src++;
	}
	return ret;
}
  •  strstr(找子字符串)
char* strstr(const char* str1, const char* str2);

返回str2第一次在str1中出现的一个指针,若str2没有在str1中出现则返回空指针

char* my_strstr(const char* str1, const char* str2)
{
	const char* cur = str1;
	const char* s1 = str1;
	const char* s2 = str2;
	assert(str1 != NULL);
	assert(str2 != NULL);

	while (*cur)
	{
		s1 = cur;
		s2 = str2;
		while ((*s1)&&(*s2)&&(*s1 == *s2))
		{
			s1++;
			s2++;
		}
		if (*s2 == '\0')
		{
			return (char*)cur;
		}
		cur++;
	}
	return NULL;
}

  •  memcpy
void* memcpy(void* dest,const void* src, size_t num);

从源位置开始向后复制num个字节的数据到目标的内存位置

函数在遇到'\0'并不会停下来

如果src和dest有重叠,复制的结果都是未定义的

//void*接收任意类型数据,void*不能解引用,不能自增自减
void* my_memcpy(void* dest,const void* src, size_t num)
{
    void* ret = dest;
    assert(dest != NULL);
    assert(src != NULL);
    
    //一个字节一个字节拷贝
    while(num--)
    {
        *(char*)dest = *(char*)src;
        dest = (char*)dest+1;
        src = (char*)src+1;
    }
    return ret;
}
  •  memmove
void* memmove(void* dest,const void* src,size_t num);

memmove处理的源内存块和目标内存块可以重叠

//方式一
void* my_memmove(void* dest,const void* src,size_t num)
{
    void* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	
	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* my_memmove(void* dest,const void* src,size_t num)
{
    void* ret = dest;
	assert(dest != NULL);
	assert(src != NULL);
	
	if (dest>src && dest<(char*)src+num)//后->前
	{
		while (num--)
		{
			*((char*)dest + num) = *((char*)src + num);
		}
	}
	else   //前->后
	{
		while (num--)
		{
			*(char*)dest = *(char*)src;
			dest = (char*)dest + 1;
			src = (char*)src + 1;
		}
	}
	return ret;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值