C/C++ 高频面试题 memcory_copy

第一个版本代码 

void MyMemcpy(char *dst,char *src,int count)
{
    while(count--)
    {
        *dst++ = *src++;
    }
}

第二个版本,将char* 改成void*, 增加通用性

void MyMemcpy(void *dst,void *src,int count)
{
     while (count--)
     {
        *(char *)dst = *(char *)src;
        dst = (char *)dst + 1;
        src = (char *)src + 1;
      }
}

另外,还有几个细节要注意,为了实现链式表达式,将返回值改为void *。此外,如果将*(char *)dst = *(char *)src;写反了,编译也是照样通过的,而找这个错误又要花费很多时间。如果你注意到src所指向的内容在函数内是不应该被改变的,所有对src所指内容的改变都必须被禁止,所以这个参数要用const修饰。改得代码如下:

void * MyMemcpy(void *dst,const void *src,int count)
{
    void *ret=dst;

    while (count--)
    {
        *(char *)dst = *(char *)src;
        dst = (char *)dst + 1;
        src = (char *)src + 1;
     }

     return ret;
}

增加空指针判断:

void * MyMemcpy(void *dst,const void *src,int count)
{
    void *ret=dst;

    if (NULL==dst||NULL ==src)
    {
        return dst;
    }
    while (count--)
    {
        *(char *)dst = *(char *)src;
        dst = (char *)dst + 1;
        src = (char *)src + 1;
     }

     return ret;
}

标准版本代码 

void * MyMemcpy(void *dst,const void *src,int count)
{
     assert(dst);
     assert(src);
     void * ret = dst;
     if (dst <= src || (char *)dst >= ((char *)src + count)) {
        
         while (count--) {
             *(char *)dst = *(char *)src;
             dst = (char *)dst + 1;
             src = (char *)src + 1;
         }
      }
      else {
         
          dst = (char *)dst + count - 1;
          src = (char *)src + count - 1;
 
          while (count--) {
          *(char *)dst = *(char *)src;
          dst = (char *)dst - 1;
          src = (char *)src - 1;
       }
    }
    return(ret);
}

大部分认为memcpy是一个char到char的拷贝的循环,担心它的效率。实际上,memcpy是一个效率最高的内存拷贝函数,他不会那么傻,来做一个一个字节的内存拷贝,在地址不对齐的情况下,他是一个字节一个字节的拷,地址对齐以后,就会使用CPU字长来拷(和dma类似),32bit或64bit,还会根据cpu的类型来选择一些优化的指令来进行拷贝。总的来说,memcpy的实现是和CPU类型、操作系统、cLib相关的。毫无疑问,它是内存拷贝里效率最高的,请放心使用。

void *mymemcpy(void *dst,const void *src,size_t num)  
{  
    assert((dst!=NULL)&&(src!=NULL));  
    int wordnum = num/4;//计算有多少个32位,按4字节拷贝  
    int slice = num%4;//剩余的按字节拷贝  
    int * pintsrc = (int *)src;  
    int * pintdst = (int *)dst;  
    while(wordnum--)*pintdst++ = *pintsrc++;  
    while (slice--)*((char *)pintdst++) =*((char *)pintsrc++);  
    return dst;  
}  

long在32机器上是4字节,64位机器上是8字节,32位机器的对齐模数就是4,64位机器的对齐模数位8。

猜你喜欢

转载自blog.csdn.net/wwxy1995/article/details/108511927