字符串(memcpy)

【1】内存拷贝函数应该如何实现?

函数原型:void * memcpy(void *memTo,memFrom,size_t size)

返回值类型:void *

参数1:void *memTo; 需要拷入的目的指针

参数2:void *memFrom; 需要拷贝的起始指针

参数3:size_t size; size_t代表unsigned int 表示拷贝的字节数

(1)具体实现版本V1.0。示例代码如下:

 1 void * memcpy(void *memTo, const void *memFrom, size_t size)
 2 {
 3     assert((memTo != NULL) && (memFrom != NULL));
 4     char *tempFrom = (char *)memFrom;
 5     char *tempTo = (char *)memTo;
 6     while (size-- > 0)
 7     {
 8         *tempTo++ = *tempFrom++;
 9     }
10     return memTo;
11 }

但是,如果用户如下调用就会出错。请看下面这种情况,两种版本的比较:

(2)具体改进实现V2.0。示例代码如下:

 1 #include <iostream>
 2 #include <cassert>
 3 using namespace std;
 4 
 5 void * MyMemMove(void *dst, const void *src, int count)
 6 {
 7     assert((dst != NULL) && (src != NULL));
 8     char* tempFrom = (char *)src;
 9     char* tempTo = (char *)dst;
10     if (tempTo <= tempFrom || tempTo >= (tempFrom + count)) 
11     {
12         while (count--) 
13         {
14             *tempTo++ = *tempFrom++;
15         }
16     }
17     else 
18     {
19         tempTo = tempTo + count - 1;
20         tempFrom = tempFrom + count - 1;
21         while (count--) 
22         {
23             *tempTo-- = *tempFrom--;
24         }
25     }
26     return  dst;
27 }
28 
29 void *memcpy(void *memTo, const void *memFrom, size_t size)
30 {
31     assert((memTo != NULL) && (memFrom != NULL));
32     char *tempFrom = (char *)memFrom;
33     char *tempTo = (char *)memTo;
34     while (size-- > 0)
35     {
36         *tempTo++ = *tempFrom++;
37     }
38     return memTo;
39 }
40 
41 void main()
42 {
43     char p1[256] = "hello,world!";
44     char p2[256] = "hello,world!";
45     MyMemMove(p1 + 1, p1, sizeof(p1));
46     memcpy(p2 + 1, p2, sizeof(p2));
47     cout << p1 << endl;   //hhello,world!
48     cout << p2 << endl;   //hhhhhhhhhhhhhh.....  error!!!!!
49     system("pause");
50 }

OK,如果用户如上调用的话,版本V1.0问题显而易见,也就是所谓的重叠内存拷贝。

这个时候就要考虑拷贝的起始地址与目的地址的大小关系。首先就要进行一步判断。如上例所示。

(3)因为内存拷贝可能不仅仅是几十个字节的任务,在实际的工作中,面对大量的字节拷贝,我们也要防止用户输入比较极端,不小心把起始地址与目的地址输入成了一个地址,那么,为了不浪费cpu做无用功。最后综合考虑,再判断一下两个指针的异同。

所以,比较满意实现V3.0。示例代码如下:

 1 void * MemMove(void *dst, const void *src, int count)
 2 {
 3     assert((dst != NULL) && (src != NULL));
 4     char* tempFrom = (char *)src;
 5     char* tempTo = (char *)dst;
 6     if (tempTo <= tempFrom || tempTo >= (tempFrom + count)) 
 7     {
 8         while (count--) 
 9         {
10             *tempTo++ = *tempFrom++;
11         }
12     }
13     else 
14     {
15         tempTo = tempTo + count - 1;
16         tempFrom = tempFrom + count - 1;
17         while (count--) 
18         {
19             *tempTo-- = *tempFrom--;
20         }
21     }
22     return  dst;
23 }

另外....

作者:kaizen
声明:本文版权归作者和博客园共有,欢迎转载。但未经作者同意必须保留此声明,且在文章明显位置给出本文链接,否则保留追究法律责任的权利。
签名:顺序 选择 循环
原文地址:https://www.cnblogs.com/Braveliu/p/2840696.html