strcpy()、memcpy()等的理解

strcpy();
原型:extern char *strcpy(char *dest,char *src);
功能:把src所指由NULL結束的字符串複製到dest所指的數組中。
說明:src和dest所指內存區域不可以重疊且dest必須有足夠的空間來容納src的字符串。
返回指向dest的指針。

char *strcpy(char *strDest, const char *strSrc)
{
    assert((strDest!=NULL) && (strSrc !=NULL));
    char *address = strDest;    
    while( (*strDest++ = * strSrc++) != '/0')
       NULL ;
    return address ;      
}

 

 

memcpy();
原型:extern void *memcpy(void* pvTo, void* pvFrom, size_t size)
功能:由src所指內存區域複製count個字節到dest所指內存區域。
說明:src和dest所指內存區域不能重疊,函數返回指向dest的指針。

void *memcpy(void* pvTo, void* pvFrom, size_t size)
{
    assert(pvTo != NULL && pvFrom != NULL);
    void* pbTo = (byte*)pvTo;
    void* pbFrom = (byte*)pvFrom; 

   /* 內存塊重疊嗎?如果重疊,就使用memmove */
    assert(pbTo>=pbFrom+size || pbFrom>=pbTo+size); 

    while(size-->0)
        *pbTo++ == *pbFrom++;
    return pvTo;
}

 

 

memset ();
原型:extern void *memset(void *buffer, int c, int count);
功能:把buffer所指內存區域的前count個字節設置成字符c。
說明:返回指向buffer的指針。

void * Memset(void* buffer, int c, int count)
{
    char* pvTo=(char*)buffer;
    assert(buffer != NULL);
    while(count-->0)
    *pvTo++=(char)c;
    return buffer;
}

 

memmove;

功能:和memcpy差不多,但是考慮內存區域重疊。

 

 

總結:

(1) strcpy只能用於字符串拷貝;而memcpy是內存拷貝,可以拷貝任何類型的數據。

(2) 當二者都進行字符串拷貝時,strcpy遇到字符串結尾'/0'即完成;而memcpy只是內存的原樣拷貝,不管遇到什麼。

 

 

(3)圖的上半部分爲源內存區域在目標內存區域右邊,下半部分爲源內存區域在目標區域左邊,源內存區域和目標內存區域都有交叉。

     memcpy()是從src的起始部分開始複製,所以雖然第一種情況下沒有問題,但如果遇到第二種情況,則會發生錯誤,如圖所示,後兩個字節在被複制前已經被覆蓋掉了。而memmove()則由於採用了不同的複製機制,所以可以正確處理第二種情況。

 

例子:

 

 

void* memmove(void *dest, const void *src,size_t n)
{
    if (n == 0) return 0;
    if (dest == NULL) return 0;
    if (src == NULL)    return 0;
    char *psrc = (char*)src;
    char *pdest = (char*)dest;
    if((dest <= psrc) || (pdest >= psrc + n)) /*檢查是否有重疊問題 */
        {
         for(int i=0; i < n; i++) /*正向拷貝*/
          {
           *pdest = *psrc;
           psrc++;
           pdest++;
          }
        }
        else /*反向拷貝*/
        {
          psrc += n;
          pdest += n;
          for(int i=0;i<n;i++)
           {
            psrc--;
            pdest--;
            *pdest = *psrc;
           }
        }
   return dest;
}

 

               

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章