天天看点

常见笔试题-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;

}

继续阅读