欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
C/C++——strcpy函數的幾種實(shí)現和詳細解析

C/C++——strcpy函數的實(shí)現 和解析

 

題目: 
    
已知strcpy函數的原型是: 
        char * strcpy(char * strDest,const char * strSrc); 
    1.
不調用庫函數,實(shí)現strcpy函數。 
    2.
解釋為什么要返回char *。

 

(一)高質(zhì)量c++編程上的答案

五、編寫(xiě)strcpy函數(10分)

已知strcpy函數的原型是

       char*strcpy(char *strDest, const char *strSrc);

       其中strDest是目的字符串,strSrc是源字符串。

1)不調用C++/C的字符串庫函數,請編寫(xiě)函數 strcpy

char *strcpy(char *strDest, const char *strSrc)

{

    assert((strDest!=NULL) && (strSrc !=NULL));    // 2

    char *address = strDest;                                          // 2

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

              NULL ;

    return address ;                                                  // 2

}

2strcpy能把strSrc的內容復制到strDest,為什么還要char * 類(lèi)型的返回值?

答:為了實(shí)現鏈式表達式。                                              // 2

例如       int length = strlen( strcpy( strDest,“hello world”) );

 

【規則6-2-3不要將正常值和錯誤標志混在一起返回。正常值用輸出參數獲得,而錯誤標志用return語(yǔ)句返回。錯誤信息可以用throw拋出。

 

2       建議6-2-1有時(shí)候函數原本不需要返回值,但為了增加靈活性如支持鏈式表達,可以附加返回值。

例如字符串拷貝函數strcpy的原型:

char *strcpy(char *strDest,const char *strSrc);

strcpy函數將strSrc拷貝至輸出參數strDest中,同時(shí)函數的返回值又是strDest。這樣做并非多此一舉,可以獲得如下靈活性:

    charstr[20];

    int length = strlen( strcpy(str, “Hello World”) );

()

 

 (二)程序員面試寶典中的答案

char* strcpy1(char *strDest, const char* strSrc)

{

       assert(strSrc != NULL );

       assert(strDest != NULL);

       int i;

       char *address = strDest;

 

    for(i = 0; strSrc[i] != '\0'; i++)

              strDest[i] = strSrc[i];

       strDest[i] = '\0';

 

       return address;

}

(三)帶有異常拋出的答案和解析
    
解說(shuō): 
    1.strcpy
的實(shí)現代碼 

 

char * strcpy3(char * strDest,const char * strSrc /*[0]*/)

{    

       if ((NULL == strDest)||(NULL == strSrc)) //[1]

              throw "Invalidargument(s)"; //[2]

 

       char * strDestCopy=strDest;  //[3]

 

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

 

       return strDestCopy;    

}

 

 

/*[0]:   規則6-1-3如果參數是指針,且僅作輸入用,則應在類(lèi)型前加const,以防止該指針在函數體內被意外修改。


    
錯誤的做法: 
    
//[1]
    (A)
如果不檢查指針的有效性,說(shuō)明答題者不注重代碼的健壯性。 
    (B)
如果檢查指針的有效性時(shí)使用((!strDest)||(!strSrc))(!(strDest&&strSrc)),說(shuō)明答題者對C語(yǔ)言中類(lèi)型的隱式轉換沒(méi)有深刻認識。在本例中((!strDest)是將char *轉換為bool即是類(lèi)型隱式轉換,這種功能雖然靈活,但更多的是導致出錯概率增大和維護成本升高。所以C++專(zhuān)門(mén)增加了bool、true、false三個(gè)關(guān)鍵字以提供更安全的條件表達式。 
    (C)
如果檢查指針的有效性時(shí)使用((strDest==0)||(strSrc==0)),說(shuō)明答題者不知道使用常量的好處。直接使用字面常量(如本例中的0)會(huì )減少程序的可維護性。0雖然簡(jiǎn)單,但程序中可能出現很多處對指針的檢查,萬(wàn)一出現筆誤,編譯器不能發(fā)現,生成的程序內含邏輯錯誤,很難排除。而使用NULL代替0,如果出現拼寫(xiě)錯誤,編譯器就會(huì )檢查出來(lái)。

DNULL == strDest 常量寫(xiě)在表達式的左邊,如果將表達式寫(xiě)錯了,寫(xiě)成了賦值,則馬上報錯;如果 將表達式改成 strDest  ==NULL,在寫(xiě)的過(guò)程中 漏寫(xiě)了 一個(gè)=,變成了 strDest  = NULL,則檢查不出錯誤來(lái),可能會(huì )出現意想不到的錯誤
    
//[2]
    (A)return new string("Invalid argument(s)");
,說(shuō)明答題者根本不知道返回值的用途,并且他對內存泄漏也沒(méi)有警惕心。從函數中返回函數體內分配的內存是十分危險的做法,他把釋放內存的義務(wù)拋給不知情的調用者,絕大多數情況下,調用者不會(huì )釋放內存,這導致內存泄漏。 
    (B)return 0;
,說(shuō)明答題者沒(méi)有掌握異常機制。調用者有可能忘記檢查返回值,調用者還可能無(wú)法檢查返回值(見(jiàn)后面的鏈式表達式)。妄想讓返回值肩負返回正確值和異常值的雙重功能,其結果往往是兩種功能都失效。應該以?huà)伋霎惓?lái)代替返回值,這樣可以減輕調用者的負擔、使錯誤不會(huì )被忽略、增強程序的可維護性。 
   
//[3]
    (A)
如果忘記保存原始的strDest值(即忘記 保留strDest的頭指針),說(shuō)明答題者邏輯思維不嚴密。 
    
//[4] 
    (A)
循環(huán)寫(xiě)成while (*strDest++=*strSrc++);,同[1](B)。 
    (B)
如果循環(huán)寫(xiě)成while (*strSrc!='\0') *strDest++=*strSrc++;,說(shuō)明答題者對邊界條件的檢查不力。這樣的話(huà),就是先判斷是否為零,然后再賦值,肯定是不會(huì )把結尾零賦給strDest的,而[4]中的循環(huán)是先賦值,再判斷是否為零,是會(huì )給strDest賦上結尾零的,如此這樣,這個(gè)形式循環(huán)體結束后,strDest字符串的末尾沒(méi)有正確地加上'\0'。

要正常的話(huà)應該寫(xiě)成:

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

strDest[i] = '\0';// strDest字符串的末尾加上'\0'

這里還有說(shuō)一句: = * right ++ 這三個(gè)符號中,*  ++的優(yōu)先級都是2級,是對等的,其次是 = , 由于 ++的特點(diǎn):是滯后使用,造成 會(huì )先賦值,再指針++

也就是說(shuō):*strDest++=*strSrc++;

     *strDest++:會(huì )拆成 *strDest strDest++兩個(gè)對等的部分

其讓人感覺(jué)到的執行順序

l      *strDest = *strSrc;

l      然后才能是 strDest++,strSrc++

 

舉個(gè)例子如下:

#define product(x) (x * x)

 int i = 3, j, k;

j = product(i++);

k = product(++i);

cout << j << "" << k << endl;//輸出為949

即使定義為#define product(x) ((x) *(x))得到的結果還是一樣
    2.
返回strDest的原始值使函數能夠支持鏈式表達式,增加了函數的附加值。同樣功能的函數,如果能合理地提高的可用性,自然就更加理想。 
    
鏈式表達式的形式如: 
        int iLength=strlen(strcpy(strA,strB)); 
    
又如: 
        char * strA=strcpy(new char[10],strB); 
    
返回strSrc的原始值是錯誤的。其一,源字符串肯定是已知的,返回它沒(méi)有意義。其二,不能支持形如第二例的表達式。其三,為了保護源字符串,形參用const限定strSrc所指的內容,把const char *作為char *返回,類(lèi)型不符,編譯報錯。

 

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
strcpy、memcpy和memset之間的區別
常見(jiàn)筆試/面試題目(一)
strcpy函數與memcpy函數
C++面試題及解釋
C語(yǔ)言中strcpy,strcmp,strlen,strcat函數原型
strcpy和memcpy的區別
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久