問題:實現一個Memcpy函數
函數簡介:c和c++使用的內存拷貝函數,memcpy函數的功能是從源src所指的內存地址的起始位置開始拷貝n個字節到目標dest所指的內存地址的起始位置中。
本題主要考慮兩點:1)內存重疊與否2)重疊內存的copy方式
無重疊的內存copy:
void *mymemcpy(void *dst,const void *src,size_t num)
{
if(NULL == dst || NULL == src){
return NULL;
}
if(des>=src+num||src>dst+num){
byte * psrc = (byte *)src;//byte 既爲unsigned char類型
byte * pdst = (byte *)dst;
while(num-->0)*pdst++ = *psrc++;
}
return dst;
}
內存重疊的copy:(依據源地址與目的地址的相對位置設計copy方式)
<pre name="code" class="cpp" style="color: rgb(51, 51, 51); font-size: 14px; line-height: 25.2px;">void * mymemcpy(void *dest, const void *src, size_t count)
{
if (dest == NULL || src == NULL)
return NULL;
char *pdest = static_cast <char*>(dest);
const char *psrc = static_cast <const char*>(psrc);
int n = count;
if (pdest > psrc && pdest < psrc+count)
{
for (size_t i=n-1; i != -1; --i)
{
pdest[i] = psrc[i];//高到低
}
}
else
{
for (size_t i= 0; i < n; i++)
{
pdest[i] = psrc[i];//低到高
}
}
return dest;
}
對於內存重疊的copy基於src與dst的相對位置,可能會有人不太清楚,這裏給出我自己畫的圖
此外,給出有關void*的深入理解,也有助於本題的解決,有興許的朋友可以看一下
void的含義
void即“無類型”,void *則爲“無類型指針”,可以指向任何數據類型。
void指針使用規範
①void指針可以指向任意類型的數據,亦即可用任意數據類型的指針對void指針賦值。例如:
int *pint;
void *pvoid;
pvoid = pint; /* 不過不能 pint = pvoid; */
如果要將pvoid賦給其他類型指針,則需要強制類型轉換如:pint = (int *)pvoid;
②在ANSI C標準中,不允許對void指針進行算術運算如pvoid++或pvoid+=1等,而在GNU中則允許,因爲在缺省情況下,GNU認爲void *與char *一樣。sizeof( *pvoid )== sizeof( char ).
void的作用
①對函數返回的限定。
②對函數參數的限定。
當函數不需要返回值時,必須使用void限定。例如: void func(int, int);
當函數不允許接受參數時,必須使用void限定。例如: int func(void)。
由於void指針可以指向任意類型的數據,亦即可用任意數據類型的指針對void指針賦值,因此還可以用void指針來作爲函數形參,這樣函數就可以接受任意數據類型的指針作爲參數。例如:
void * memcpy( void *dest, const void *src, size_t len );
void * memset( void * buffer, int c, size_t num );