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

来源:互联网 发布:saucony跑鞋矩阵 编辑:程序博客网 时间:2024/05/16 09:46

我们先来看下字符串的存储,字符串一般是用字符数组的方式存储,问题来了,我们都知道字符串有一个结束符"\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标准库中的说明)

实现如下:

//实现方式1char *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;}//实现方式2char *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>//实现方式1char *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;}//实现方式2char *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;}


 

 


 

 

 

 

 

 

 

 

 

0 0
原创粉丝点击