C语言函数string.h 之 内存copy函数memcpy


昨天去国迈科技公司面试,其中有一道笔试题是实现内存复制函数memcpy(),记得在网上有很多人讨论过这样的题目,但并没有自己写代码实现过。

我在答题卡上给出的代码如下(带下划线红色字为有误或设计不良的地方):

void *memcpy(void *desc, const void *src, size_t n)
{
	char *p = desc;
	char *q = src;
	int i = 0;
	while( p != NULL && q != NULL && (i++) < n)
	{
		*p++ = *q++;
	}
	return desc;
}

事实上,上面的代码编译时:rror C2440: 'initializing' : cannot convert from 'void *' to 'char *' Conversion from 'void*' to pointer to non-'void' requires an explicit cast,也即不能从void*覆盖【转换】char*,因此需要把desc和src转换为char*类型再赋值给*p。同时并不需要每次while循环都要进行p!=NULL && q!=NULL比较操作。


内存复制函数:

memcpy()

C和C++中使用memcpy()作为内存复制函数,memcpy()函数的功能是从源src所指的内存地址开始复制n个字节到目标dest所指的内存地址的起始地址中。

函数原型:

void *memcpy(void *dest, const void *src, size_t count);
所需头文件:

C语言中要加入文件,C++要加入文件;
返回内容:

函数返回指向dest的指针;
说明:
1、src和dest所指的
内存区域可能重叠所以函数不能确保source所在重叠区域在复制之前不被覆盖了,因此程序员应该控制是否内存重叠;
2、根据ANSI标准,不能对void*进行算法操作,所以要把void*转换成char*类型,因为memcpy()实现的是逐个字节复制的;
3、因为传递的参数是void *类型,因此实参可以是各种类型的指针;

4、首先要判断指针的值不能为空如果dest为空肯定不能复制内存空间,src为空则等同无内存可复制。

实现代码:

void *memcpy(void * dest, const void * src, size_t count)
{
	assert(dest != NULL && src != NULL);
	char *tmp = (char*)dest;
	const char *s = (char*)src;
	for(size_t i=0; i < count; i ++)
		tmp[i] = s[i];
	return dest;
}

相关函数:memmove()

函数原型:void *memmove( void* dest, const void* src, size_t count )

函数功能:由src所指内存区域复制count个字节到dest所指内存区域。

特别说明如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。但复制后src内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。


与strcpy的区别:
1、复制内容不同,strcpy只能复制字符串,而memcpy可以复制任意内容,如字符数组、整形、结构体等;
2、复制的方法不同,strcpy不需要指定长度,它遇到被复制字符的串结束符’\0’才结束,所以容易溢出,而memcpy则是根据第3个参数决定复制的长度;
3、用途不同,通常在复制字符串时用strcpy,而需要复制其他数据类型时一般用memcpy。


你可能感兴趣的:(C语言函数)