找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 2387|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

C語言中strcpy函數(shù)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:108615 發(fā)表于 2016-3-13 17:20 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
講解比較的詳細(xì)!

已知strcpy函數(shù)的原型是
char* strcpy(char* strDest,const char* strSrc);
1.不調(diào)用庫函數(shù),實(shí)現(xiàn)strcpy函數(shù)
2.解釋為什么要返回char*;
1.strcpy的實(shí)現(xiàn)代碼
char* strcpy(char* strDest,const char* strSrc)
{
if((strDest == NULL) || (strSrc == NULL)) //[1]
  throw "Invalid Arguments"; //[2]
  //assert((strDest!=NULL) && (strSrc !=NULL));
char* strDestCopy = strDest; //[3]
while((*strDest++ = *strSrc++) != '\0')//[4]
  ;
return strDestCopy;
}
[1]
(A)不檢查指針的有效性,說明設(shè)計(jì)者不注重程序的健壯性
(B)檢查指針的有效性時(shí)使用((!strDest) || (!strSrc))或(!(strDest && strSrc)),說明對(duì)C語言中
類型隱式轉(zhuǎn)換沒有深刻認(rèn)識(shí),在本例中char*轉(zhuǎn)換為bool即是類型隱式轉(zhuǎn)換,這種功能雖然靈活,但
是更多的是導(dǎo)致出錯(cuò)概率的增大和維護(hù)成本的增高
(C) 檢查指針的有效性時(shí)使用((strDest==0)||(strSrc==0))說明答題者不知道使用常量的好處。直接使用字面常量(如本例中的0)會(huì)
減少程序的可維護(hù)性。0雖然簡單,但程序中可能出現(xiàn)很多處對(duì)指針的檢查,萬一出現(xiàn)筆誤,編譯器不能發(fā)現(xiàn),生成的程序內(nèi)含邏輯
錯(cuò)誤,很難排除。而使用NULL 代替0,如果出現(xiàn)拼寫錯(cuò)誤,編譯器就會(huì)檢查出來。
[2]
(A)return new string("Invalid arguments");,說明答題者根本不知道返回值得用途,并且它對(duì)內(nèi)存泄露也沒有警惕心,從函數(shù)體中
返回函數(shù)體內(nèi)分配的內(nèi)存是十分危險(xiǎn)的做法,他把釋放內(nèi)存的義務(wù)拋給不知情的調(diào)用者,絕大多數(shù)情況下,調(diào)用者不會(huì)釋放內(nèi)存,這
導(dǎo)致內(nèi)存泄露
(B)return 0;,說明答題者沒有掌握異常機(jī)制。調(diào)用者有可能忘記檢查返回值,調(diào)用者還可能無法檢查返回值(見后面的鏈?zhǔn)奖磉_(dá)式)
。妄想讓返回值肩負(fù)返回正確值和異常值的雙重功能,其結(jié)果往往是兩種功能都失效。應(yīng)該以拋出異常來代替返回值,這樣可以減輕
調(diào)用者的負(fù)擔(dān)、使錯(cuò)誤不會(huì)被忽略、增強(qiáng)程序的可維護(hù)性。
[3]
(A)忘記保存原始的strDest值,說明答題者邏輯思維不嚴(yán)密。
[4]
(A)循環(huán)寫成while (*strDest++=*strSrc++);,同[1](B)。
(B)循環(huán)寫成while (*strSrc!='\0') *strDest++=*strSrc++;,說明答題者對(duì)邊界條件的檢查不力。循環(huán)體結(jié)束后,strDest字符串的末
尾沒有正確地加上'\0'。
2.返回strDest的原始值使函數(shù)能夠支持鏈?zhǔn)奖磉_(dá)式,增加了函數(shù)的“附加值”。同樣功能的函數(shù),如果能合理地提高的可用性,自然
就更加理想。鏈?zhǔn)奖磉_(dá)式的形式如:
int iLength=strlen(strcpy(strA,strB));
又如:
char * strA=strcpy(new char[10],strB);
返回strSrc的原始值是錯(cuò)誤的。其一,源字符串肯定是已知的,返回它沒有意義。其二,不能支持形如第二例的表達(dá)式。其三,為了
保護(hù)源字符串,形參用const限定strSrc所指的內(nèi)容,把const char *作為char *返回,類型不符,編譯報(bào)錯(cuò)。
1.引言
  本文的寫作目的并不在于提供C/C++程序員求職面試指導(dǎo),而旨在從技術(shù)上分析面試題的內(nèi)涵。文中的大多數(shù)面試題來自各大論
壇,部分試題解答也參考了網(wǎng)友的意見。
   許多面試題看似簡單,卻需要深厚的基本功才能給出完美的解答。企業(yè)要求面試者寫一個(gè)最簡單的strcpy函數(shù)都可看出面試者在
技術(shù)上究竟達(dá)到了怎樣的程 度,我們能真正寫好一個(gè)strcpy函數(shù)嗎?我們都覺得自己能,可是我們寫出的strcpy很可能只能拿到10分
中的2分。讀者可從本文看到strcpy 函數(shù)從2分到10分解答的例子,看看自己屬于什么樣的層次。此外,還有一些面試題考查面試者敏
捷的思維能力。
  分析這些面試題,本身包含很強(qiáng)的趣味性;而作為一名研發(fā)人員,通過對(duì)這些面試題的深入剖析則可進(jìn)一步增強(qiáng)自身的內(nèi)功。
2.找錯(cuò)題
  試題1:
void test1()
{
 char string[10];
 char* str1 = "0123456789";
 strcpy( string, str1 );
}
  試題2:
void test2()
{
 char string[10], str1[10];
 int i;
 for(i=0; i<10; i++)
 {
  str1 = 'a';
 }
 strcpy( string, str1 );
}
  試題3:
void test3(char* str1)
{
 char string[10];
 if( strlen( str1 ) <= 10 )
 {
  strcpy( string, str1 );
 }
}
 解答:
  試題1字符串str1需要11個(gè)字節(jié)才能存放下(包括末尾的’\0’),而string只有10個(gè)字節(jié)的空間,strcpy會(huì)導(dǎo)致數(shù)組越界;
   對(duì)試題2,如果面試者指出字符數(shù)組str1不能在數(shù)組內(nèi)結(jié)束可以給3分;如果面試者指出strcpy(string, str1)調(diào)用使得從str1內(nèi)存起
        復(fù)制到string內(nèi)存起所復(fù)制的字節(jié)數(shù)具有不確定性可以給7分,在此基礎(chǔ)上指出庫函數(shù)strcpy工作方式的給10 分;
  對(duì)試題3,if(strlen(str1) <= 10)應(yīng)改為if(strlen(str1) < 10),因?yàn)閟trlen的結(jié)果未統(tǒng)計(jì)’\0’所占用的1個(gè)字節(jié)。
  剖析:
  考查對(duì)基本功的掌握:
  (1)字符串以’\0’結(jié)尾;
  (2)對(duì)數(shù)組越界把握的敏感度;
  (3)庫函數(shù)strcpy的工作方式,如果編寫一個(gè)標(biāo)準(zhǔn)strcpy函數(shù)的總分值為10,下面給出幾個(gè)不同得分的答案:
  2分
void strcpy( char *strDest, char *strSrc )
{
  while( (*strDest++ = * strSrc++) != ‘\0’ );
}
  4分
void strcpy( char *strDest, const char *strSrc )
//將源字符串加const,表明其為輸入?yún)?shù),加2分
{
  while( (*strDest++ = * strSrc++) != ‘\0’ );
}
  7分
void strcpy(char *strDest, const char *strSrc)
{
 //對(duì)源地址和目的地址加非0斷言,加3分
 assert( (strDest != NULL) && (strSrc != NULL) );
 while( (*strDest++ = * strSrc++) != ‘\0’ );
}
  10分
//為了實(shí)現(xiàn)鏈?zhǔn)讲僮鳎瑢⒛康牡刂贩祷,?分!
char * strcpy( char *strDest, const char *strSrc )
{
 assert( (strDest != NULL) && (strSrc != NULL) );
 char *address = strDest;
 while( (*strDest++ = * strSrc++) != ‘\0’ );
  return address;
}






分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表