由strcpy()剖析編程規範

先給出幾種實現方式:c++

方式一:算法

<span style="font-size:14px;">char* strcpy(char* des,const char* source)
 {
 char* r=des;
 while((*(des++)=*(source++))!='\0');
 return r;
 }
</span>

方式二:編程

char * strcpy(char * strDest,const char * strSrc)
{
if ((NULL==strDest) || (NULL==strSrc)) //[1]

throw "Invalid argument(s)"; //[2]

char * strDestCopy = strDest; //[3]

while ((*strDest++=*strSrc++)!='\0'); //[4]

return strDestCopy;
}

方式三:安全

<span style="font-size:14px;">char * strcpy(char * strDest, const char * strSrc)

{

	if ((!strDest) || (!strSrc))

		throw "Invalid argument(s)";

	char * strDestCopy = strDest;

	while ((*strDest++ = *strSrc++) != '\0');

	return strDestCopy;
}</span>

方式四:函數

<span style="font-size:14px;">char * strcpy(char * strDest, const char * strSrc)

{
	assert((NULL == strDest) || (NULL == strSrc));
	char * strDestCopy = strDest;

	while ((*strDest++ = *strSrc++) != '\0');

	return strDestCopy;
}</span>

還有其餘實現方式。。。。。。。。。。性能

[1]
(A)不檢查 指針 的有效性,說明答題者不注重代碼的健壯性。
(B)檢查指針的有效性時使用((!strDest)||(!strSrc))或(!(strDest&&strSrc)),說明答題者對C語言中類型的隱式轉換沒有深入認識。在本例中char *轉換爲bool便是類型隱式轉換,這種功能雖然靈活,但更多的是致使出錯機率增大和維護成本升高。因此C++專門增長了bool、true、false三個 關鍵字 以提供更安全的 條件表達式
(C)檢查指針的有效性時使用((strDest==0)||(strSrc==0)),說明答題者不知道使用 常量 的好處。直接使用字面 常量 (如本例中的0)會減小程序的可維護性。0雖然簡單,但程序中可能出現不少處對指針的檢查,萬一出現筆誤, 編譯器 不能發現,生成的程序內含邏輯錯誤,很難排除。而使用NULL代替0,若是出現拼寫錯誤, 編譯器 就會檢查出來。
[2]
(A)return new string("Invalid argument(s)");,說明答題者根本不知道返回值的用途,而且他對 內存泄漏 也沒有警戒心。從函數中返回函數體內分配的內存是十分危險的作法,他把釋放內存的義務拋給不知情的調用者,絕大多數狀況下,調用者不會 釋放 內存,這致使內存泄漏。
(B)return 0;,說明答題者沒有掌握異常機制。調用者有可能忘記檢查返回值,調用者還可能沒法檢查返回值(見後面的鏈式表達式)。妄想讓返回值肩負返回正確值和異常值的雙重功能,其結果每每是兩種功能都失效。應該以 拋出異常 來代替 返回值 ,這樣能夠減輕調用者的負擔、使錯誤不會被忽略、加強程序的可維護性。
[3]
(A)忘記保存原始的strDest值,說明答題者邏輯思惟不嚴密。
[4]
(A)循環寫成while (*strDestCopy++=*strSrc++);,同[1](B)。
(B)循環寫成while (*strSrc!='\0') *strDest++=*strSrc++;,說明答題者對邊界條件的檢查不力。循環體結束後,strDest字符串的末尾沒有正確地加上'\0'。
⒉返回strDest的原始值使函數可以支持鏈式 表達式 ,增長了函數的「附加值」。一樣功能的函數,若是能合理地提升的可用性,天然就更加理想。
鏈式表達式的形式如:
int iLength=strlen(strcpy(strA,strB));
又如:
char * strA=strcpy(new char[10],strB);
返回strSrc的原始值是錯誤的。其一,源字符串確定是已知的,返回它沒有意義。其二,不能支持形如第二例的表達式。其三,爲了保護源字符串, 形參 用const限定strSrc所指的內容,把const char *做爲char *返回,類型不符,編譯報錯。 本人喜歡第四種實現方式!
此函數想到的:
這麼一個小不點的函數,能夠從三個方面考查:

1)編程風格;spa

2)出錯處理;指針

3)算法複雜度分析(用於提升性能)。code




相關文章
相關標籤/搜索