今天去面試,面試官出了一個關於memcpy的函數原型的實現的問題,原本這個問題是很簡單的,可是不知道當時怎麼腦子一抽居然寫錯了,真是」累覺不愛」了.感受這份工做算是泡湯了,算了事情發生了,錯過了也就錯過了.既然這樣就把這件事情記錄下來,給本身提個醒~ c++
這個問題對於接觸過的朋友天然不難,問題在於給本身一個分析的方法,遇到相似的問題怎麼解決. 面試
memcpy實現內存拷貝,根據這個問題,咱們能夠提取出下面幾點: 函數
1.能夠拷貝任何數據,數據類型不能受限 spa
2.源數據不能被改變 指針
經過上面兩點能夠肯定函數原型爲void *memcpy(void *dest, const void *src),如今分析一下這些足夠了嗎?這個函數拷貝何時結束,當時我就用了這個函數原型,因爲是拷貝的任意數據,因此不能指定一個明確的結束標誌,既然這樣那麼只有明確的指定拷貝的大小才能夠.因此函數原型變成這樣void *memcpy(void *dest, void *src, size_t count);好吧,函數原型既然已經確認了,剩下的應該就是寫函數了,先等等,先別急着寫函數,實際上對於C語言的開發者來講,重要的不是函數功能的實現,重要的是函數出錯時的處理,若是你用的是Java或者C#大不了拋個異常出來,軟件崩潰一下,不會對其餘形成任何影響;C這東西弄很差會把整個系統弄癱瘓,所謂」兵馬未動,糧草先行」,我麼仍是先考慮考慮出錯的問題吧!咱們根據函數原型來分析, blog
void *memcpy(void *dest, const void *src, size_t count); 內存
1.空指針的問題,若是dest、src二者或者二者之一爲NULL,那麼天然能沒得完了; 開發
2.拷貝大小count爲小於等於0的值,天然也是不正確的; get
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是無符號類型的,size_t的定義爲:typedef unsigned int size_t;
因此count<=0,只會判斷==0的狀況,若是傳入-1,會產生一個很大的無符號整型.
但願別人注意,改過的程序以下:
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;
}