手写memcpy,strcpy,memset,strcat,strcmp

41 篇文章 0 订阅

目录

 

1)memcpy

2)strcpy

3) memset

4)strcat

5)strcmp


1)memcpy

函数声明:void *memcpy(void *dst, const void *src, size_t n); // //dst:目的地址, src:源地址  n:要拷贝的字节数

但是标准memcpy(),对于地址重叠的情况,该函数的行为是未定义的。//If copying takes place between objects that overlap, the behavior is undefined.

但是面试时,手写memcpy()时就需要考虑地址重叠的情况。

另外,标准库也提供了地址重叠时的内存拷贝函数:memmove(),那么为什么还要考虑重写memcpy()函数呢?

因为memmove()函数的实现效率问题,该函数把源字符串拷贝到临时buf里,然后再从临时buf里写到目的地址,增加了一次不必要的开销。

//dst:目的地址, src:源地址 count:要拷贝的字节数
void* memcpy(void* dst, const void* src, size_t count)
{
	// 输入判断
	if(dst==src || count==0)
		return dst;
	
	if(dst==nullptr || src==nullptr)
		return nullptr;
	
	char *pdst = (char *)dst;
	char *psrc = (char *)src;
	int cnt = count;
 
	// 内存拷贝
	if (pdst > psrc && pdst < (psrc + count)) // 自后向前(目标地址比源地址比原地址高且与源空间重叠,如果自前向后拷贝会覆盖掉目标地址前面的内容)
	{
		pdst += (cnt -1);
		psrc += (cnt -1);
		while (cnt--)
		{
			*pdst-- = *psrc--;
		}
	}
	else // 自前向后
	{
		while (cnt--)
		{
			*pdst++ = *psrc++;
		}
	}
 
	return dst;
}

2)strcpy

//没有考虑重叠版本
char* strcpy(char *dst,const char *src)  
{  

	// 宏函数,条件为假 输出括号里的信息,并终止程序 
    assert(dst != nullptr&&src != nullptr);
	
    char *cur = dst;  
    while((* cur++ = * src++) != '\0')   
        ;  
    return dst;  
}  

//考虑重叠

char* strcpy(char* dst, const char* src)
{
	
    assert((dst != NULL) && (src != NULL));
    if(dst==src)
		return dst;
	
	char* cur = dst;
    int size = strlen(src) + 1;
    if(cur > src && cur < src + len)
    {
        cur = cur + size - 1;
        src = src + size - 1;
        while(size--)
        {
            *cur-- = *src--;
        }
    }
    else
    {
        while(size--)
        {
            *cur++ = *src++;
        }
    }
    return dst;
}

 

3) memset

void* memset(void *dst, int val, size_t size) {
    char *s_dst = dst;
    char ch = val;
    if (s_dst == NULL) {
        return NULL;
    }
    
    while (size--) {
        *s_dst++ = ch;
    }
    
    return dst;
}

4)strcat

char* strcat(char* dst, const char* src)
{
    char* ret = dst;

    while(*dst != '\0')
        ++dst;

    while((*dst++ = *src++) != '\0');
    return ret;
}

5)strcmp

基本形式为strcmp(str1,str2),若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数

int strcmp(const char* str1, const char* str2)
{

    while(*str1 == *str2 && *str1 != '\0')
    {
        ++str1;
        ++str2;
    }
    return *str1 - *str2;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值