程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 關於memcpy的實現

關於memcpy的實現

編輯:關於C語言

今天去面試,面試官出了一個關於memcpy的函數原型的實現的問題,本來這個問題是很簡單的,但是不知道當時怎麼腦子一抽竟然寫錯了,真是”累覺不愛”了.感覺這份工作算是泡湯了,算了事情發生了,錯過了也就錯過了.既然這樣就把這件事情記錄下來,給自己提個醒~

這個問題對於接觸過的朋友自然不難,問題在於給自己一個分析的方法,遇到類似的問題怎麼解決.

memcpy實現內存拷貝,根據這個問題,我們可以提取出下面幾點:

1.可以拷貝任何數據,數據類型不能受限

2.源數據不能被改變

通過上面兩點可以確定函數原型為void *memcpy(void *dest, const void *src),現在分析一下這些足夠了嗎?這個函數拷貝什麼時候結束,當時我就用了這個函數原型,由於是拷貝的任意數據,所以不能指定一個明確的結束標志,既然這樣那麼只有明確的指定拷貝的大小才可以.所以函數原型變成這樣void *memcpy(void *dest, void *src, size_t count);好吧,函數原型既然已經確認了,剩下的應該就是寫函數了,先等等,先別急著寫函數,實際上對於C語言的開發者來說,重要的不是函數功能的實現,重要的是函數出錯時的處理,如果你用的是Java或者C#大不了拋個異常出來,軟件崩潰一下,不會對其他造成任何影響;C這東西弄不好會把整個系統弄癱瘓,所謂”兵馬未動,糧草先行”,我麼還是先考慮考慮出錯的問題吧!我們根據函數原型來分析,

void *memcpy(void *dest, const void *src, size_t count);

1.空指針的問題,如果dest、src兩者或者兩者之一為NULL,那麼自然能沒得完了;

2.拷貝大小count為小於等於0的值,自然也是不正確的;

3.目標有沒有足夠的大小容納源數據,這個我們在函數內部似乎也無法進行保證,但是我們自己也要想到

4.內存地址有沒有重疊,這個我們暫時不考慮了。

有了上面的提示寫起來自然比較簡單了

#include <stdio.h>

void *memcpy(void *dest, const void *src, size_t count)

{

if (NULL == dest || NULL == src || count <= 0)

return NULL;

while (count--)

*dest++ = *src++;

return dest;

}

上面這段代碼在Linux中使用gcc編譯是沒錯的,但是會有警告,所以改成這樣:

#include <stdio.h>

void *memcpy(void *dest, const void *src, size_t count)

{

if (NULL == dest || NULL == src || count <= 0)

return NULL;

while (count--)

*(char *)dest++ = *(char *)src++;

return dest;

}

OK,也就這樣了,要是面試官再問起內存重疊的問題,你再和他侃侃.

我的面試算是泡湯了.

總結:不要著急慢慢來,根據需求推出原型,根據原型推斷問題,這算是個教訓吧!!!

 

 

補充

在這裡非常感謝博客園的求道於盲  這位好心的網友指出了我程序中的兩個錯誤

1.返回了一個

2.size_t

所以

希望別人注意

void *memcpy(void *dest, const void *src, int count)

{

void *ptr = dest;

if (NULL == dest || NULL == src || count <= 0)

return NULL;

 

while (count--)

*(char *)dest++ = *(char *)src++;

 

return ptr;

}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved