看面試題的時候有個題目是不使用庫函數,實現strcpy函數.(字符串拷貝函數)
這個是我寫的代碼,在機器上編譯過了.
void my_strcpy(char *t,char *s){ while((*t++=*s++)); }
看了很多帖子,發現我這個代碼的問題還是很多的.即使這么簡單的一個小程序也有很多的東西需要考慮.下面總結:
1.關於函數返回值.我寫的是void,即函數不返回參數.所以我這個函數的唯一目的是將s地址字符串復制到t上.不返回任何信息.這樣寫的代碼在以后使用是不方便的.林銳<高質量C/C++編程指南>里提到:返回char *的目的是為了實現鏈式表達式.如:
int length=strlen(strcpy(strDest,"HelloWorld"));//如果沒有返回char *那么要多寫幾行代碼非常麻煩.
2.保留原串的問題.
正因第一個錯誤犯下導致了第二個錯誤的直接產生,那就是保留目標串首地址的問題.既然要返回目標串的話肯定是返回目標串的首地址.即return t.而在函數里對t要進行地址移動操作,所以在開始要保存t的地址.
char *strDest=t; //t的地址保留在strDest,這樣直接返回strDest即可,而可以操作t.
3.關於源串,目標串的檢查問題.
這個主要是檢查源串,目標串指針的合法性.
assert((t!=NULL) && (s!=NULL)); //如果t,s均!=NULL那么就繼續執行,如果不是的話並退出程序並輸出錯誤信息.
這樣一來,比較合格的strcpy()函數完成:(這個也是林銳博士在高質量C/C++編程當中的源代碼)
char *my_strcpy(char *t,char *s){ char *strDest=t; assert((*t)!=NULL && (*s)!=NULL); while((*t++=*s++)); return strDest; }
其實在GNU C的strcpy源代碼當中並沒有對串指針合法性的檢測.看了網上帖子大家爭論的原因是:assert()這個函數非常的繁瑣耗時.所以GNU C是為了提高效率,而且本意是如果出錯則程序會crash,而檢查crash則是程序員慢慢調試.庫函數則是以效率為先!