這幾個函數在面試的時候經常被考到,但沒看過要準确又完美的寫出來也不是易事,傳說IBM曾經也考過寫strcpy原型,說明這幾個函數真的很有代表性,是以記于此處以便溫習。
以下皆經本人調試過。
1、Strcat函數原型如下:
char *strcat(char *strDest, const char *strScr) //将源字元串加const,表明其為輸入參數
{
char * address = strDest; //該語句若放在assert之後,編譯出錯
assert((strDest != NULL) && (strScr != NULL)); //對源位址和目的位址加非0斷言
while(*strDest) //是while(*strDest!=’\0’)的簡化形式
{ //若使用while(*strDest++),則會出錯,因為++是不受循環
strDest++; //限制的。是以要在循環體内++;因為要是*strDest最後指
} //向該字元串的結束标志’\0’。
while(*strDest++ = *strScr++) //是while((*strDest++ = *strScr++)!=’\0’)的簡化形式
{
NULL; //該循環條件内可以用++,
} //此處可以加語句*strDest=’\0’;有無必要?
return address; //為了實作鍊式操作,将目的位址傳回
}
以下是在VC6.0中調試的例子,函數名用strcata代替。
#include <stdio.h>
#include <assert.h>
char *strcata(char *strDest,const char *strScr)
{
char * address = strDest;
assert((strDest != NULL) && (strScr != NULL));
while(*strDest)
{
strDest++;
}
while(*strDest++ = *strScr++)
{
NULL;
}
return address;
}
void main()
{
char str1[100]={"i love"};
char str2[50]={"China"};
printf("%s\n",strcata(str1,str2));
}
2、Strcpy函數原型如下:
char *strcpy(char *strDest, const char *strScr)
{
char *address=strDest;
assert((strDest != NULL) && (strScr != NULL));
while(*strScr) //是while(*strScr != ’\0’)的簡化形式;
{
*strDest++ = *strScr++;
}
*strDest = '\0'; //當strScr字元串長度小于原strDest字元串長度
return address; //時,如果沒有改語句,就會出錯了。
}
以下是在VC6.0中調試的例子,函數名用strcpya代替。
#include <stdio.h>
#include <assert.h>
char *strcpya(char *strDest, const char *strScr)
{
char *address = strDest;
assert((strDest != NULL) && (strScr != NULL));
while(*strScr)
{
*strDest++ = *strScr++;
}
*strDest = '\0';
return address;
}
void main()
{
char str1[100]={"i love"};
char str2[50]={"China"};
printf("%s\n",strcpya(str1,str2));
}
3、Strcmp函數原型如下:
int strcmp (const char *str1,const char *str2)
{
int len = 0;
assert((str1 != '\0') && (str2 != '\0'));
while(*str1 && *str2 && (*str1 == *str2))
{
str1++;
str2++;
}
return *str1-*str2;
}
以下是在VC6.0中調試的例子,函數名用strcmpa代替。
#include <stdio.h>
#include <assert.h>
int strcmpa (const char *str1,const char *str2)
{
int len = 0;
assert((str1 != '\0') && (str2 != '\0'));
while(*str1 && *str2 && (*str1==*str2))
{
str1++;
str2++;
}
return *str1-*str2;
}
void main()
{
char str1[100] = {"i love"};
char str2[50] = {"China "};
printf("%d\n",strcmpa(str1,str2));
}
4、Strlen函數原型如下:
int strlen(const char *str)
{
int len = 0;
assert(str != NULL);
while(*str++)
{
len++;
}
return len;
}
以下是在VC6.0中調試的例子,函數名用strlena代替。
#include <stdio.h>
#include <assert.h>
int strlena(const char *str)
{
int len = 0;
assert(str != NULL);
while(*str++)
{
len++;
}
return len;
}
void main()
{
char str1[100] = {"i love"};
char str2[50] = {"China "};
printf("%d\n",strlena(str1));
}
轉自:
http://hi.baidu.com/cometrue/item/f340a885a25a07874514cf0e
實作strlen()函數
一)strlen()函數的源代碼
[cpp] view plain copy
- size_t __cdecl strlen (const char * str)
- {
- const char *eos = str;
- while( *eos++ ) ;
- return( eos - str - 1 );
- }
二)傳說常見的一個筆試題:不使用中間變量求const字元串長度,即實作求字元串長度庫函數strlen函數。
函數接口聲明如下:
[cpp] view plain copy
- int strlen (const char *p);
①實作方法一: [cpp] view plain copy
- int strlen(const char *str)
- {
- if ('\0' == *str)
- return 0;
- else
- return strlen(str+1) + 1;
- }
②實作方法二: [cpp] view plain copy
- int strlen(const char *str)
- {
- return *str?(strlen(++str) + 1) : 0;
- }
+ 評分标準
試題1:
void test1()
{
char string[10];
char* str1 ="0123456789";
strcpy(string, str1 );
} 試題2:
void test2()
{
char string[10],str1[10];
inti; 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;
}
類似的我們可以寫出一個10分的strlen函數
int strlen( const char *str ) //輸入參數const
{
assert( strt!= NULL ); //斷言字元串位址非0
intlen;
while((*str++) != '\0' )
{
len++;
}
returnlen;
}