memcpy、memmove、memset、strcpy的区别

memcpy

函数原型:

函数功能:memcpy函数的功能是从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中。函数返回值指向dest的指针。不考虑内存重叠

[cpp]  view plain  copy
  1. #include<stdio.h>  
  2. #include<assert.h>  
  3. #include<string.h>  
  4. void* Memcpy(void* dst, const void* src, size_t size)  
  5. {  
  6.     assert(dst);  
  7.     assert(src);  
  8.     char* pdst = (char*)dst;  
  9.     const char* psrc = (const char*)src;  
  10.       
  11.     while (size--)  
  12.     {  
  13.         *pdst++ = *psrc++;  
  14.     }  
  15.       
  16.     return dst;  
  17. }  
  18. int main()  
  19. {  
  20.     char dst[20];  
  21.     memset(dst, '\0'sizeof(dst));  
  22.     char src[] = "hello";  
  23.     printf("%s\n", Memcpy(dst, src, strlen(src)));  
  24.     return 0;  
  25. }  

memcpy函数的优化

[cpp]  view plain  copy
  1. #include<stdio.h>  
  2. #include<assert.h>  
  3. #include<string.h>  
  4. void* Memcpy(void* dst, const void* src, size_t size)  
  5. {  
  6.     int len = size / 4; //计算size要拷的次数  
  7.     int mod = size % 4;//计算余下的字符要拷的次数  
  8.     int* pdst = (int *)dst;//强转为int,这样一次性可以拷4个字节  
  9.     const int* psrc = (const int*)src;  
  10.     //没有余下字符就返回dst,结束拷贝  
  11.     if (mod == 0)  
  12.     {  
  13.         return dst;  
  14.     }  
  15.     while (len--)  
  16.     {  
  17.         *pdst++ = *psrc++;  
  18.     }  
  19.     char* p = (char*)dst;  
  20.     p += len*sizeof(int);//指向余下的字符  
  21.     const char* q = (const char*)src;  
  22.     q += len*sizeof(int);  
  23.     while (mod--)  
  24.     {  
  25.         *p++ = *q++;  
  26.     }  
  27.     return dst;  
  28. }  
  29. int main()  
  30. {  
  31.     char dst[20];  
  32.     memset(dst, '\0'sizeof(dst));  
  33.     const char* src = "hello";  
  34.     printf("%s\n", Memcpy(dst, src, strlen(src)));  
  35.     return 0;  
  36. }  


 

memmove
函数原型:

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

[cpp]  view plain  copy
  1. #include<stdio.h>  
  2. #include<assert.h>  
  3. #include<string.h>  
  4. void* Memmove(void* dst, const void* src, size_t size)  
  5. {  
  6.     assert(dst);  
  7.     assert(src);  
  8.     char* pdst = (char*)dst;  
  9.     const char* psrc = (const char*)src;  
  10.     if (pdst > psrc + size || pdst < psrc)  
  11.     {  
  12.         while (size--)  
  13.         {  
  14.             *pdst++ = *psrc++;  
  15.         }  
  16.     }  
  17.     else  
  18.     {  
  19.         pdst = pdst + size-1;  
  20.         psrc = psrc + size-1;  
  21.         while (size--)  
  22.         {  
  23.             *pdst-- = *psrc--;  
  24.         }  
  25.     }  
  26.     return dst;  
  27. }  
  28. int main()  
  29. {  
  30.     char dst[20];  
  31.     memset(dst, '\0'sizeof(dst));  
  32.     char src[] = "hello";  
  33.     printf("%s\n", Memmove(dst, src, strlen(src)));  
  34.     return 0;  
  35. }  

memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。

但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。

memmove的处理措施:

(1)当源内存的首地址大于目标内存的首地址时,实行正向拷贝

(2)当源内存的首地址小于目标内存的首地址时,实行反向拷贝

memset
函数原型:

函数功能:将s所指向的某一块内存中的前n个 字节的内容全部设置为ch指定的ASCII值, 第一个值为指定的内存地址,块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作, 其返回值为指向s的指针。

[cpp]  view plain  copy
  1. #include<stdio.h>  
  2. #include<assert.h>  
  3. void* Memset(void* str, char c, size_t size)  
  4. {  
  5.     assert(str);  
  6.     char* s = (char*)str;  
  7.     while (size--)  
  8.     {  
  9.         *s++ = c;  
  10.     }  
  11.     return str;  
  12. }  
  13. int main()  
  14. {  
  15.     char s[] = "hello world";  
  16.     printf("%s\n", s);  
  17.     Memset(s, '0', strlen(s));  
  18.     printf("%s\n", s);  
  19.     return 0;  
  20. }  

strcpy  strncpy

函数原型:

函数功能:strcpy把从src地址开始且含有'\0'结束符的字符串复制到以dest开始的地址空间。返回指向dest的指针。src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。

strncpy把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回dest。

[cpp]  view plain  copy
  1. #include<stdio.h>  
  2. #include<assert.h>  
  3. #include<string.h>  
  4. char* Strcpy(char* dst,const char*src)  
  5. {  
  6.     assert(dst);  
  7.     assert(src);  
  8.     char* pdst = dst;  
  9.     while (*src)  
  10.     {  
  11.         *dst++ = *src++;  
  12.     }  
  13.     return pdst;  
  14. }  
  15. int main()  
  16. {  
  17.     const char src[] = "hello,hello bit";  
  18.     char dst[] = "";  
  19.     printf("%s\n", Strcpy(src, dst));  
  20.     return 0;  
  21. }  

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

 

[cpp]  view plain  copy
  1. #include<stdio.h>  
  2. #include<assert.h>  
  3. char* Strncpy(char* dst, const char* src, size_t size)  
  4. {  
  5.     assert(dst);  
  6.     assert(src);  
  7.     char* pdst = dst;  
  8.     while (size--)  
  9.     {  
  10.         *dst++ = *src++;  
  11.     }  
  12.     return pdst;  
  13. }  
  14. int main()  
  15. {  
  16.     char dst[20];  
  17.     memset(dst, '\0'sizeof(dst));  
  18.     const char* src = "hello";  
  19.     printf("%s\n", Strncpy(dst, src, strlen(src)));  
  20.     return 0;  
  21. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值