【內(nèi)存操作函數(shù)】
字符串操作函數(shù)中有一個strcpy的函數(shù),它可以拷貝字符類型,那么有沒有不關(guān)心類型的函數(shù)呢?這個,當(dāng)然是有滴,大師們早就將他們寫到庫里面了,
自寫內(nèi)存操作函數(shù)
。1.memcpy() 用來復(fù)制內(nèi)存,其原型為:
void * memcpy ( void * dest, const void * src, size_t num );
memcpy() 會復(fù)制 src 所指的內(nèi)存內(nèi)容的前 num 個字節(jié)到 dest 所指的內(nèi)存地址上。
memcpy() 并不關(guān)心被復(fù)制的數(shù)據(jù)類型,也就是說它可以操作任意類型,只是逐字節(jié)地進行復(fù)制,這給函數(shù)的使用帶來了很大的靈活性,可以面向任何數(shù)據(jù)類型進行復(fù)制。
需要注意的是:
>>1.dest 指針要分配足夠的空間,也即大于等于 num 字節(jié)的空間。如果沒有分配空間,會出現(xiàn)斷錯誤。
>>2.dest 和 src 所指的內(nèi)存空間不能重疊(如果發(fā)生了重疊,使用 memmove()會更加安全)。
與 strcpy() 不同的是,memcpy() 會完整的復(fù)制 num 個字節(jié),不會因為遇到“\0”而結(jié)束。
【返回值】返回指向 dest 的指針。注意返回的指針類型是 void,使用時一般要進行強制類型轉(zhuǎn)換。
【函數(shù)實現(xiàn)】
#include <stdio.h>#include <string.h>#define MAX 20void* my_memcpy(void *dest,const void *src,size_t count){ int *buf1=(int *)dest; int *buf2=(int *)src; int *pret=(int *)dest; while (count--) { *buf1=*buf2; buf1++; buf2++; } return pret;}int main(){ int arr[MAX]={0}; int brr[5]={1,2,3,4,5}; int size=sizeof(brr)/sizeof(brr[0]); int i=0; my_memcpy(arr,brr,size); for (i=0;i<MAX;i++) { printf("%d ",arr[i]); } printf("\n"); return 0;}
結(jié)果:
這個就將原數(shù)組中的0一個不漏的打印出來了,好神奇_^_^_
有了這個函數(shù),就解決了一部分拷貝的問題,為什么說一部分呢,接下來,聽我慢慢道來,
電腦資料
《自寫內(nèi)存操作函數(shù)》(http://www.stanzs.com)。這個時候,我有一個問題,如果我給定一個數(shù)組arr[10]={1,2,3,4,5,6,7,8,9,10};我想把它的{5,6,7,8}拷貝到{7,8,9,10}上去最后打印出數(shù)組arr結(jié)果應(yīng)該是{1,2,3,4,5,6,5,6,7,8};接下來看代碼實現(xiàn):
#include <stdio.h>void* my_memcpy(void *dest,const void *src,size_t count){ int *buf1=(int *)dest; int *buf2=(int *)src; int *p=(int *)dest; while (count--) { *buf1=*buf2; buf1++; buf2++; } return p;}int main(){ int arr[10]={1,2,3,4,5,6,7,8,9,10}; int i=0; my_memcpy(arr+6,arr+4,16); for (i=0;i<10;i++) { printf("%d ",arr[i]); } printf("\n"); return 0;}
結(jié)果:
這個結(jié)果怎么和預(yù)先預(yù)測的結(jié)果不一樣呢_~~_這就是出現(xiàn)上面注意的第二點dest 和 src 所指的內(nèi)存空間不能重疊,如果出現(xiàn)重疊,就會出現(xiàn)想不到的問題。