總結C/C++面試中能夠會碰到的字符串指針題。本站提示廣大學習愛好者:(總結C/C++面試中能夠會碰到的字符串指針題)文章只能為提供參考,不一定能成為您想要的結果。以下是總結C/C++面試中能夠會碰到的字符串指針題正文
前言
不知道大家有沒有這種領會,很多面試題看似復雜,卻需求深沉的根本功才干給出完滿的解答。企業要求面試者寫一個最復雜的strcpy函數都可看出面試者在技術上終究到達了怎樣的水平,我們能真正寫好一個strcpy函數嗎?我們都覺得自己能,可是我們寫出的strcpy很能夠只能拿到10分中的2分。讀者可從本文看到 strcpy函數從2分到10分解答的例子,看看自己屬於什麼樣的層次。此外,還有一些面試題考察面試者矯捷的思想才能。
剖析這些面試題,自身包括很強的興趣性;而作為一名研發人員,經過對這些面試題的深化分析則可進一步加強本身的內功。
找錯題
試題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個字節才干寄存下(包括末尾的'\0'),而string只要10個字節的空間,strcpy會招致數組越界;
對試題2,假如面試者指出字符數組str1不能在數組內完畢可以給3分;假如面試者指出strcpy(string,str1)
調用使得從str1內存起復制到string內存起所復制的字節數具有不確定性可以給7分,在此根底上指出庫函數strcpy任務方式的給10分;
對試題 3,if(strlen(str1) <= 10)
應改為if(strlen(str1) <10)
,由於strlen的後果未統計'\0'所占用的1個字節。
分析:
考察對根本功的掌握:
(1)字符串以'\0'開頭;
(2)對數組越界掌握的敏感度;
(3)庫函數strcpy的任務方式,假如編寫一個規范strcpy函數的總分值為10,上面給出幾個不同得分的答案:
2分
以下是援用片段:
void strcpy( char *strDest, char *strSrc ) { while( (*strDest++ = * strSrc++) != ‘\0' ); }
4分
以下是援用片段:
void strcpy( char *strDest, const char *strSrc ) // 將源字符串加const,標明其為輸出參數,加2分 { while( (*strDest++ = * strSrc++) != ‘\0' ); }
7分
以下是援用片段:
void strcpy(char *strDest, const char *strSrc) { //對源地址和目的地址加非0斷言,加3分 assert( (strDest != NULL) &&(strSrc != NULL) ); while( (*strDest++ = * strSrc++) != ‘\0' ); }
10分
以下是援用片段:
// 為了完成鏈式操作,將目的地址前往,加3分! char * strcpy( char *strDest, const char *strSrc ) { assert( (strDest != NULL) &&(strSrc != NULL) ); char *address = strDest; while( (*strDest++ = * strSrc++) != ‘\0' ); return address; }
從2分到10分的幾個答案我們可以清楚的看到,小小的strcpy居然隱藏著這麼多玄機,真不是蓋的!需求多麼扎實的根本功才干寫一個完滿的 strcpy啊!
(4)對strlen的掌握,它沒有包括字符串末尾的'\0'。
讀者看了不同分值的 strcpy版本,應該也可以寫出一個10分的strlen函數了,完滿的版本為:
以下是援用片段:
int strlen( const char *str ) //輸出參數const { assert( strt != NULL ); //斷言字符串地址非0 int len; while( (*str++) != '\0' ) { len++; } return len; }
試題4:
以下是援用片段:
void GetMemory( char *p ) { p = (char *) malloc( 100 ); } void Test( void ) { char *str = NULL; GetMemory( str ); strcpy( str, "hello world" ); printf( str ); }
試題5:
以下是援用片段:
char *GetMemory( void ) { char p[] = "hello world"; return p; } void Test( void ) { char *str = NULL; str = GetMemory(); printf( str ); }
試題6:
以下是援用片段:
void GetMemory( char **p, int num ) { *p = (char *) malloc( num ); } void Test( void ) { char *str = NULL; GetMemory( &str, 100 ); strcpy( str, "hello" ); printf( str ); }
試題7:
以下是援用片段:
void Test( void ) { char *str = (char *) malloc( 100 ); strcpy(str, "hello" ); free( str ); ... //省略的其它語句 }
解答:
試題4傳入中GetMemory( char *p )
函數的形參為字符串指針,在函數外部修正形參並不能真正的改動傳入形參的值,執行完
char *str = NULL;GetMemory( str );
後的str依然為NULL;
試題5中
char p[] = "hello world"; return p;
的p[]數組為函數內的部分自動變量,在函數前往後,內存曾經被釋放。這是許多順序員常犯的錯誤,其本源在於不了解變量的生活期。
試題6的GetMemory防止了試題4的問題,傳入GetMemory的參數為字符串指針的指針,但是在GetMemory中執行請求內存及賦值語句 tiffanybracelets
*p = (char *) malloc( num );
後未判別內存能否請求成功,應加上:
if ( *p == NULL ) { ...//停止請求內存失敗處置 }
試題6的Test函數中也未對malloc的內存停止釋放。
試題7存在與試題6異樣的問題,在執行
char *str = (char *) malloc(100);
後未停止內存能否請求成功的判別;另外,在free(str)
後未置str為空,招致能夠變成一個“野” 指針,應加上:
str = NULL;
分析:
試題4~7考察面試者對內存操作的了解水平,根本功扎實的面試者普通都能正確的答復其中50~60的錯誤。但是要完全解答正確,卻也絕非易事。
對內存操作的考察次要集中在:
(1)指針的了解;
(2)變量的生活期及作用范圍;
(3)良好的靜態內存請求和釋放習氣。
再看看上面的一段順序有什麼錯誤:
以下是援用片段:
swap( int* p1,int* p2 ) { int *p; *p = *p1; *p1 = *p2; *p2 = *p; }
在swap函數中,p是一個“野”指針,有能夠指向零碎區,招致順序運轉的解體。在VC++中DEBUG運轉時提示錯誤“Access Violation”。該順序應該改為:
以下是援用片段:
swap( int* p1,int* p2 ) { int p; p = *p1; *p1 = *p2; *p2 = p; }
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或許任務能帶來一定的協助,假如有疑問大家可以留言交流。