我們以前在拷貝一個字元串時隻想到過strcpy()函數拷貝,但是這個函數在使用時存在一定的缺點,一方面它隻能用來拷貝字元串并不能拷貝其他類型的資料,另一方面它隻有在遇到'\0'時才結束拷貝,是以容易溢出。是以,就引入memcpy()這個記憶體操作函數。首先,先看一下二者的差別:

memcpy:
1.函數原型:void *memcpy( void *dest, const void *src, size_t count );
2.了解:此函數在進行拷貝時,所給出的兩塊記憶體必須是不相關聯的
如果給一個類型已經給定的數組,例如 int arr1[]={1,2,3,4,5,6,7,8};要求将其複制到數組 int arr2[] 中去,我們一定想到的是下面這種辦法:
int *my_memcpy(int *dest,const int *src,int sz)
{
int *pdest = dest;
while(sz--)
{
*pdest = *src;
src++;
pdest++;
}
return dest;
}
試想想,假如就給了上邊這段代碼,如果要拷貝的是 char 型的字元串呢?!或者其他類型的數呢?!那這段程式就得一直被修改,這樣就特别麻煩,是以,在此代碼的基礎上做一些修改就可以打破這樣的局限性
void *my_memcpy(void *dest,const void *src,int sz)
{
char *pdest = (char*)dest;
const char *psrc = (const char *)src;
assert(dest);
assert(src);
while(sz--)
{
*pdest = *psrc;
psrc++;
pdest++;
}
return dest;
}
顯然這是将類型改為了 void* 型的,這樣 void* 類型的指針就可以指向任意類型的指針,在函數内部将其強制類型轉換為 char* 類型同樣也是為了程式的實用性,使其在複制時是一個位元組一個位元組地拷貝
memmove:
1.函數原型: void *memmove( void *dest, const void *src, size_t count );
2.了解:将src所指向的字元串拷貝 count 個到 dest 所指向的字元串中,這兩塊記憶體可以是相關聯的,也可以是 不相關聯的。
讨論記憶體相關聯的情況———假設給定數組 int arr1[ ]={1,2,3,4,5,6,7,8},要将其輸出為12123678,即将123拷貝到從2 開始的位置:
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
void *my_memmove(void *dest,const void *src,int count)
{
char *pdest = (char *)dest;
char *psrc = (char *)src;
assert(dest);
assert(src);
if((pdest>psrc)&&(pdest<(psrc+count))) //dest指向于src和src+count的中間
{
while(count--)
{
*(pdest+count) = *(psrc+count);
//pdest--;
//psrc--;
}
}
else
{
while(count--)
{
*pdest++ = *psrc++;
}
}
return dest;
}
int main()
{
int arr1[]={1,2,3,4,5,6,7,8};
int sz = sizeof(arr1);
int i = 0;
my_memmove(arr1+2,arr1,3*sizeof(int));
for(i=0; i<sizeof(arr1)/sizeof(arr1[0]); i++)
{
printf("%d ",arr1[i]);
}
system("pause");
return 0;
}
這段代碼同樣存在一定的局限性,同樣也可以将指針類型改為void* 類型,但需注意的是 void* 類型的指針不能自加自減,也不能解引用,是以必須将其強制類型轉換
memset :
1.函數原型:void *memset( void *dest, intc, size_tcount );
2.了解:此函數是對 dest 所指向的某一塊記憶體的前 count 個位元組初始化為c對應的ASCCII值
void *my_memset(void *dest,int ch,size_t count)
{
char *pdest = (char *)dest;
while(count--)
{
*pdest = ch;
pdest++;
}
return dest;
}