天天看點

常見筆試題-Strcat,strcpy,strcmp,Strlen函數原型 + Strlen幾種實作

這幾個函數在面試的時候經常被考到,但沒看過要準确又完美的寫出來也不是易事,傳說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

  1. size_t __cdecl strlen (const char * str)  
  2. {        
  3.         const char *eos = str;  
  4.         while( *eos++ ) ;  
  5.         return( eos - str - 1 );  
  6. }  

二)傳說常見的一個筆試題:不使用中間變量求const字元串長度,即實作求字元串長度庫函數strlen函數。

函數接口聲明如下:

[cpp] view plain copy

  1. int strlen (const char *p);  

①實作方法一: [cpp] view plain copy

  1. int strlen(const char *str)     
  2. {       
  3.     if ('\0' == *str)    
  4.         return 0;             
  5.     else          
  6.         return strlen(str+1) + 1;           
  7. }  

②實作方法二: [cpp] view plain copy

  1. int strlen(const char *str)     
  2. {                   
  3.     return *str?(strlen(++str) + 1) : 0;   
  4. }  

+ 評分标準

試題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;

}

繼續閱讀