C/C++標準庫函數的實現

須要的頭文件:#include <string.h>
c++

原型: 數組

extern void* memcpy(void *dest, const void *src, size_t n);
//If copying takes place between objects that overlap, the behavior is undefined

功能:由src指向地址爲起始地址的連續n個字節的數據複製到以destin指向地址爲起始地址的空間內。 函數

注意: 測試

1.source和destin所指的內存區域能夠重疊,可是若是source和destin所指的內存區域重疊,那麼這個函數並不可以確保source所在重疊區域在拷貝以前被覆蓋。而使用memmove能夠用來處理重疊區域。函數返回指向destin的指針。
2.strcpy和memcpy主要有如下3方面的區別。
2.一、複製的內容不一樣。strcpy只能複製字符串,而memcpy能夠複製任意內容,例如字符數組、整型、結構體、類等。
2.二、複製的方法不一樣。strcpy不須要指定長度,它遇到被複制字符的串結束符"\0"才結束,因此容易溢出。memcpy則是根據其第3個參數決定複製的長度。
2.三、用途不一樣。一般在複製字符串時用strcpy,而須要複製其餘類型數據時則通常用memcpy
3.若是目標數組destin自己已有數據,執行memcpy()後,將覆蓋原有數據(最多覆蓋n)。若是要追加數據,則每次執行memcpy後,要將目標數組地址增長到你要追加數據的地址。
注意:source和destin都不必定是數組,任意的可讀寫的空間都可。

4.標準庫函數提供了地址重疊時的內存拷貝函數:memmove()由於memmove()函數把源字符串拷貝到臨時buf裏,而後再從臨時buf裏寫到目的地址,增長了一次沒必要要的開銷,可是能夠解決內存重疊拷貝問題。 spa

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void *memcpy(void *dst,const void *src,size_t size);

int mian(int argc,char *argv[])
{
   char buf[100]="abcdefgh";
   Memcpy(buf+2,buf,5);//memcpy(buf+2,buf,5);
   printf("%s\n",buf+2);
}
//若是函數的參數能夠是任意類型指針,那麼應聲明其參數爲void *
void *Memcpy(void *dst,const void *src, size_t size)
{
   char *psrc;
   char *pdst;
   if(dst == NULL|| src == NULL) return NULL;
   if((src<dst)&&(char*)src+size>(char*)dst)//src和dst內存重疊,則自後向前拷貝
   {
       psrc = (char*)src+size-1;
       pdst = (char*)dst+size-;
       while(size--)
       {
          *pdst-- = *psrc--;
        }
    }
    else
    {
        psrc = (char*)src;
        pdst = (char*)dst;
        while(size--)
        {
           *pdst++ = *psrc++;
        }
     }
     return dst;
}

PS:size_t 類型定義在cstddef.h頭文件中,該文件是C標準庫的頭文件stddef.h的C++版。它是一個與機器相關的unsigned類型,其大小足以保證存儲內存中對象的大小。 指針

在C++中,size_t的引入加強了程序在不一樣平臺上的可移植性。size_t是針對系統定製的一種數據類型,通常是整型,由於C/C++標準只定義最低的位數,而不是必需的固定位數。並且在內存裏,對數的高位對齊存儲仍是低位對齊存儲各系統都不同。固然,有些是編譯器或系統已經給定義好的。經測試發現,在32位系統中size_t是4字節的,而在64位系統中,size_t是8字節的,這樣利用該類型能夠加強程序的可移植性。
code

關於void* :若是函數的參數能夠是任意類型指針,那麼聲明其參數爲void*; 對象

典型的如內存操做函數memcpy和memset的函數原型分別爲: 內存

void * memcpy(void *dest, const void *src, size_t size);
void * memset ( void * buffer, int c, size_t size );
這樣任何類型的指針均可以傳入memcpy和memset中,真實體現了內存操做函數的意義,yinwei
相關文章
相關標籤/搜索