strcpy,memcpy,memmove,memset,strncpy

來自: http://hi.baidu.com/lkmoses/blog/item/3c553dc4778701169c163d57.html

strcpy,memcpy,memmove,memset,strncpy,
一.函數分別介紹:
1、memcpy:
原型:extern void *memcpy(void *dest, const void *src, unsigned int count);
用法:#include<string.h>
功能:由src所指內存區域複製count個字節到dest所指內存區域。
說明:src和dest所指內存區域不能重疊,函數返回指向dest的指針。
注意:和strcpy相比,memcpy不是遇到’\0’就結束,而是一定會拷貝完n個字節。

2、memset:
函數原型:
extern void *memset(void *s, int c, size_t n)
功能:將已開闢內存空間s的首n個字節的值設爲值c。將s中的前n個字符替換爲c,並返回s。
memset常用於內存空間的初始化。
memset的深刻內涵:用來對一段內科空間全部設置爲某個字符,一般用在對定義的字符串進行初始化爲:memset(a, ‘\0’, sizeof(a));

3、void *memmove(void *s, const void *ct, size_t n)
與memcpy類似,所不同的是,當對象重疊時,該函數仍能正確執行

4、strncpy(s, t, n)
把t指向的字符串中前n個字符複製到s指向的位置。

二.下面重點來講解memcpy和memmove的區別:
這兩個函數的函數原型(除了名字)是一樣的:
void *memcpy(void *dst, const void *src, size_t count):
void *memmove(void *dst, const void *src, size_t count);
它們都是從src所指向的內存中複製count個字節到dst所指內存中,並返回dst的值。當源內存區域和目標內存區域無交叉時,兩者的結果都是一樣的。但有交叉時不一樣。源內存和目標內存交叉的情況有以下兩種:(左邊爲低地址)

1、


即:dst<=src 且 dst+count>src
2、


即:src<dst且src+count>dst
下面將針對這兩種情況來討論。針對第一種交叉情況情況,dst<src且dst+count>src,memcpy和memmove的結果是一樣的。請看下面的例子講解:
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
memcpy(a, a+4, sizeof(int)*6);和memmove(a, a+4, sizeof(int)*6);結果是:
4567896789

針對第二種情況,src<dst且src+count>dst,memcpy和memmove的結果是不一樣的。請看下面的例子:
int arr[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
memcpy(a+4, a, sizeof(int)*6)


memmove(a+4, a, sizeof(int)*6)



下面是這兩個函數的具體實現:
void *memcpyMy(void *dst, const void *src, size_t count){
void *address = dst;

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

return dst;
}

void *memmoveMy(void *dst, const void *src, size_t count){
void *address = dst;

if (dst <= src || (char*)dst >= (char *)src + count)
{
   while (count --)
   {
    *(char *)address = *(char *)src;
    address = (char *)address + 1;
    src = (char *)src + 1;
   }
}else{
   address = (char *)address + count - 1;
   src = (char *)src + count - 1;
   while (count --)
   {
    *(char *)address = *(char *)src;
    address = (char *)address - 1;
    src = (char *)src - 1;
   }
}

return dst;
}
以上兩段代碼是在vc6.0下通過測試的。


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