總結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;
}
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或許任務能帶來一定的協助,假如有疑問大家可以留言交流。