C语言库函数strcpy与memcpy函数比较

我们先来看下字符串的存储,字符串一般是用字符数组的方式存储,问题来了,我们都知道字符串有一个结束符"\0",存储字符串的字符数组的长度是多少呢?我们来看个例子:char str[] = "123456";
这里str是一个字符数组,它存放了一个字符串"123456",由于字符串还有一个结束符"\0",所以此数组的长度为7而不是6。转入正题,strcpy函数与memcpy函数的比较

strcpy和memcpy都是标准C库函数,其在string.h头文件中声明,它们有下面的特点。

strcpy提供了字符串的复制。即strcpy只用于字符串复制,并且它不仅复制字符串内容之外,还会复制字符串的结束符。

memcpy提供了一般内存的复制(例如字符数组、整型、结构体、类等)。即memcpy对于需要复制的内容没有限制,因此用途更广。

memcpy 和 strcpy 的区别:

<1> 复制的内容和可复制的范围不同。strcpy仅能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。

<2> 复制的方法和方式不同。strcpy不需要指定的长度,遇到被复制字符的串结束符’\0’才结束,容易溢出;而memcpy则根据第三个参数size_t n决定复制的长度。

<3> 用途不同。通常在复制字符串时用strcpy,而复制其他数据类型时一般用memcpy。

<4> 如果初始时destin本身已有数据,执行memcpy后,将从头开始覆盖原有数据,但至多仅能覆盖n个字节。

接下来我们来看看strcpy函数与memcpy函数函数原型以及实现,使大家更好更深刻的理解他们的特点

strcpy函数的原型:

char *strcpy(char *strDest,const char *strSrc);

或char *strcpy(char *s1,const char *s2);

函数说明:

*从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中,函数返回指向dest的指针。

*strc和des所指内存区域不可以重叠且dest必须有足够的空间来存储src字符串(C标准库中的说明)

实现如下:

//实现方式1
char *strcpy(char *strDest, const char *strSrc) // 实现strSrc到strDest的复制
{
	if ((strDest == NULL) || (strSrc == NULL)) //判断参数strDest和strSrc的有效性
	{
		return NULL;
	} 

	char *strDestCopy = strDest; //保存目标字符串的首地址
	while ((*strDest++ = *strSrc++)!='\0'); //把strSrc字符串的内容复制到strDest下

	return strDestCopy;
}

//实现方式2
char *strcpy(char *s1,const char *s2)
{
	if (NULL == s1 || NULL == s2)
		return NULL;

	char *s = s1;

	for(s = s1;(*s1++ = *s2++) != '\0';)
		;
	return s;
}


 

strcpy函数的实现1说明

*代码首先判断传入的参数strDest和strSrc是否为NULL,如果是则返回NULL。

*把strDest的值保存到strDestCopy指针中。

*对strSrc和strDest两个指针进行循环移动,并不断复制strSrc内存的值到strDest内存中,直到遇到'\0'(注意:算法上连同'\0'都复制了)。

*由于已经保存了strDest指针的值,因此这里只需返回strDestCopy的值,而函数调用完后返回的就是strDest的值。

strcpy函数的实现2说明与实现1类似

 

memcpy函数的原型:

char  *memcpy(void *memTo, const void *memFrom, size_t size)

函数说明:

*从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中,函数返回指向dest的指针。

*source和destin所指内存区域不能重叠,如果重叠,则函数的行为不确定(C标准库中的说明)

 

实现如下:

	 if((memTo == NULL) || (memFrom == NULL)) //memTo和memFrom必须有效 
		 return NULL;

	 char *tempFrom = (char *)memFrom; //保存memFrom首地址
	 char *tempTo = (char *)memTo; //保存memTo首地址
	 
	 while(size -- > 0) //循环size次,复制memFrom的值到memTo中
	 *tempTo++ = *tempFrom++ ; 
 
	 return tempTo;

 

memcpy函数的实现说明

*代码首先判断传入的参数memTo和memFrom是否为NULL,如果是则返回NULL。

*指明memFrom的类型为char *,同时将memFrom的值保存到tempFrom中、指明memTo类型也为char *,同时将memTo的值保存到tempTo中。

*对tempFrom和tempTo两个指针进行循环移动,并不断复制tempFrom内存的值到tempTo内存中,直到size长度不大于0。

*由于已经保存了memTo指针的值,因此这里只需返回tempTo的值,而函数调用完后返回的就是memTo的值。

附上测试源码:

strcpy函数测试

#include <stdio.h>
#include <stdlib.h>

//实现方式1
char *strcpy(char *strDest, const char *strSrc) // 实现strSrc到strDest的复制
{
	if ((strDest == NULL) || (strSrc == NULL)) //判断参数strDest和strSrc的有效性
	{
		return NULL;
	} 

	char *strDestCopy = strDest; //保存目标字符串的首地址
	while ((*strDest++ = *strSrc++)!='\0'); //把strSrc字符串的内容复制到strDest下

	return strDestCopy;
}

//实现方式2
char *strcpy(char *s1,const char *s2)
{
	if (NULL == s1 || NULL == s2)
		return NULL;

	char *s = s1;

	for(s = s1;(*s1++ = *s2++) != '\0';)
		;
	return s;
}



int main()
{
	char strSrc[] = "Hello World!"; //将被复制的字符数组
	char strDest[20]; //目的字符数组
	strcpy(strDest,strSrc);

	printf("strDest: %s\n", strDest);

	system("pause");

	return 0;
}


memcpy测试源码:

#include <stdio.h>
#include <stdlib.h>

 void *memcpy(void *memTo, const void *memFrom, size_t size)
 {
	 if((memTo == NULL) || (memFrom == NULL)) //memTo和memFrom必须有效 
		 return NULL;

	 char *tempFrom = (char *)memFrom; //保存memFrom首地址
	 char *tempTo = (char *)memTo; //保存memTo首地址
	 
	 while(size -- > 0) //循环size次,复制memFrom的值到memTo中
	 *tempTo++ = *tempFrom++ ; 
 
	 return memTo;
 }
 
 int main()
 {
	char strSrc[] = "Hello World!"; //将被复制的字符数组
	char strDest[20]; //目的字符数组

	 memcpy(strDest, strSrc, sizeof(strSrc)); //复制strSrc的前4个字符到strDest中

	 printf("strDest: %s\n", strDest);
	 
	 system("pause");

	 return 0;
}


 

 


 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值