C语言中的Strcpy和memcpy、strlen实现

1.memcpy的实现

1)第一个版本

void* memcpy(void* dest,const void* stc,unsigned int count)
{
	if(src == NULL) ||(dest == NULL)
		return;
	while(count--)
		*dest++ = *src++;
	return dest;
}
  • dest都指到哪里去了?怎么着也得备份一下dest的值,好让函数返回的指针是从头开始的
    考虑一下指针类型,如果dest和src的指针类型不一样,不能直接++赋值. 例如: int* p和 char*q, p++指针的值是4个4个加(0,4,8),q++是1个1个加(0,1,2,3,4)

2)第二个版本

void* memcpy(void* dest,const void* src,size_t count)
{
	char* tmp = dest;
	const char*s = src;

	while(count--)
		*tmp++ = *s++;
	
	return dest;
}
  • 能否改进? src和dest都强制转换成char*类型的指针,那么copy一定是一个字节一个字节的完成?那么第三版来了

3)第三个版本

void* memcpy(void* dst,const void* src,size_t num)
{
	int nchunks = num/sizeof(det); //按CPU位宽拷贝
	int slice = num%sizeof(dst);   //剩下的按字节拷贝
	
	unsigned long* s = (unsigned long*)src;
	unsigned long* d = (unsigned long*)dst;

	while(nchunks--)
		*d++ = *s++;
	while(slice--)
		*((char*)d++) = *((char*)s++);
	
	return dst;	
}
  • 看着没什么问题了,可是如果dst和src地址不对齐,copy效率岂不降低? 是否需要先处理一下地址不对齐的情况?

4)第四个版本

  • 内存重叠问题是指目的地址的内存空间的首地址,包含在源内存空间中,这两段内存空间有了交集,因而在使用memcpy进行内存复制操作时,这段重叠的内存空间会被破坏.这种情况在应用程序级代码中一般不会出现的,而在驱动或内核级代码中要十分小心,尽量使用memmove函数

在这里插入图片描述

  • 虽然原来的数据不再是原来的数据(dest+size>=src),但拷贝的数据是原来的数据,使用memcpy函数可以得到正确的结果.因此,在使用memcpy这个函数之前,还需要做一个判断,如果dest<=src你才能使用这个函数不过完全没有必要, 解决办法,从高地址向地地址copy
void *memcpy(void* dest,const void*src,size_t count)
{
	char* d;
	const char*s

	if(dest > (src+size)) || (dest <src))
	{
		d = dest;
		s = stc;
		while(count--)
		{
			*d++ = *s++;
		}
	}
	return dest;
}

5)memcpy总结

    1. 不要破坏传进来的形参,定义新的临时变量来操作
  • 2.考虑指针的类型,不同类型的指针不能直接++赋值

  • 3.overlap情况下需要从高地址处向前copy

2.strcpy的实现

1)第一版本:普通版本

char* strcpy(char* s1,const char* s2)//src:s2  , dest:s1
{
	char* save = s1;
	while(*s1 != '\0')
		*s1++ = *s2++;
	return (save);
}

2)第二版本:考虑到overlap

char* strcpy(char* dst,const char* src)
{
	assert(dst != NULL);//作用是如果它的条件返回错误,则终止程序执行,原型定义:
	assert(src != NULL);//substring直接返回从角标为indx的字符开始一直到结尾的字符串,"abcde".substring(2) 返回的是 "cde"。
	char* ret = dst;
	memcpy(dst,src,strlen(src)+1); /* strlen确实不计算结尾的*/
	return ret;

}

3.strlen

int strlen(char* src)
{
	int i = 0;
	while(*src++ != '\0')
		i++;
	return i;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值