strlen、strcpy和strcmp源码

时间:2024-04-16 12:42:38

1、不使用库函数实现strcpy

#include <assert.h>

char *strcpy(char *dst, const char *src)

{

   assert((dst != NULL) && (src != NULL));

  char *tmp = dst;

   while ((*dst++ = *src++) != '\0')

  {                 /* nothing */;

  }

  return tmp;

}

需要注意几个方面的问题:

1、注意编程风格。比如,使用dst、src这样增强可读性的名字。

2、使用断言assert来检验输入参数的有效性。

assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回false,则终止程序执行。可以在任何时候启用和禁用断言验证,因此可以在测试时启用断言,而在部署时禁

用断言。

3、使用const来约束src,表明src对应的内容不能被修改。

4、返回dst,以便实现链式表达式这样的机制。

2、strlen函数源码

size_t strlen_b(const char * str)

{

const char *cp =  str;

while (*cp++ );

return (cp - str - 1 );

}

3、微软strcmp函数源码

int __cdecl strcmp (const char *src, const char *dst)

{

  int ret = 0 ;

  while(!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)

  {

    ++src;   ++dst;

  }

  if ( ret < 0 )

  ret = -1 ;

  else if ( ret > 0 )

  ret = 1 ;

  return( ret );

}

4、面试中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。

5、对strlen的掌握,它没有包括字符串末尾的'\0'

  看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为:

 int strlen( const char *str ) //输入参数const,2分

{     assert( strt != NULL ); //断言字符串地址非0,3分     int len;     while( (*str++) != '\0' ) // 3分     {         len++;     }     return len;  }