zoukankan      html  css  js  c++  java
  • 字符串(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
    声明:本文版权归作者和博客园共有,欢迎转载。但未经作者同意必须保留此声明,且在文章明显位置给出本文链接,否则保留追究法律责任的权利。
    签名:顺序 选择 循环
  • 相关阅读:
    微信小程序 --- 获取当前坐标
    微信小程序 --- 缓存数据
    微信小程序 --- 音乐的播放和控制
    微信小程序 --- webSocket
    微信小程序 --- 文件的上传和下载
    微信小程序 --- 选择图片和拍照
    微信小程序 --- loading提示框
    微信小程序 --- toast消息提示框
    Atitit.attilax软件研发与项目管理之道
    Atitit.attilax软件研发与项目管理之道
  • 原文地址:https://www.cnblogs.com/Braveliu/p/2840696.html
Copyright © 2011-2022 走看看