C风格字符串常用标准库函数的实现与注意点

1、strcpy()函数的实现

char *MyStrCopy(char *strDesc, const char *strSource)
{
      assert((NULL != strDesc)&&(NULL != strSource));
      char *pszTemp = strDesc;
      while(((*pszTemp++) = (*strSource++)) != '\0');
      return strDesc;
}

strcpy()函数的实现是面试出现率很高的题目,这个函数的实现看起来很简单,只有几行代码,但是这几行代码却能体现一个程序员的很多东西。

首先看传参,一般应把目的字符串作为第一个参数,而源字符串作为第二个参数,这样比较符合人们的习惯;

第二个函数第一行的断言assert(),理论上字符串函数的参数不应为空,所以判空是很有必要的;

然后第三行代码的临时变量的创建,这样逻辑思维更严密;

第四行代码中的'\0'判断,如果不加这个判断说明对数据类型的隐式转换理解的不够深刻;

最后的返回值,是为了支持链式表达式,链式表达式即为了便于拷贝完函数之后直接使用返回值。

所以一个strcpy()函数能够看出你的编码习惯,以及编码风格,及对C语言的基础数据类型的理解。

2、strcmp()函数的实现

int MyStrCmp(const char *strFirst,const char *strSecond)
{
      assert((NULL != strFirst)&&(NULL != strSecond));
      int iRet = 0;
     while(!(iRet = (*(unsigned char*)strFirst)-(*(unsigned char*)strSecond))&&(*strFirst != '\0'))
     {
           strFirst++;
           strSecond++;
     }
    if (iRet < 0)
    {
          iRet = -1;
     
    else if (iRet > 0) 
    {
          iRet = 1;
    
    return iRet;

}

strcmp()函数是比较两个字符串的大小,相等返回0,strFirst大于strSecond时返回1,小于时返回-1,此函数应注意以下几点:

1、字符大小判断时应使用*(unsigned char*)strFirst,而不是*strFirst,因为默认传入的参数为有符号数,但是字符串的ASCII没有负值,若不转化为无符号数这回在减法实现时可能会出现错误,如*strFirst的值为1,而*strSecond的值为255,这时做减法,如果是有符号的,则作为无符号数计算时ret = -254,结果为负值,正确;作为有符号数计算时ret = 2,结果为正值,错误。

2、!(iRet = (*(unsigned char*)strFirst)-(*(unsigned char*)strSecond))&&(*strFirst!='\0')语句中的&&*strFirst的使用,如果没有添加后面的语句,那么当两个字符串相等时,最后都是‘\0’,还是相等所以两个字符串会继续‘++’,这就导致计算结果有误。
3、strcat()函数实现

char *MyStrCat(char *strDesc, const char *strSource)
{
          assert((NULL != strDesc)&&(NULL != strSource));
          char *pszAddr = strDesc;
          while(*strDesc != '\0')
          {
                  strDesc++;
          }
         while(((*strDesc++) = (*strSource++)) != '\0');
         return pszAddr;
}
该函数的实现字符串连接的功能,即把strSourse字符串连接到strDesc的末尾,但是该函数的实现实际上是有问题的,因为如果strDesc容量过小,这时如果连接时就会出现越界问题,这个问题在标准库函数的定义是就存在。该函数的实现在 while(*strDesc != '\0')这句要注意一下,不能直接用 while(*strDesc++ != '\0'),因为如果用后面的语句当while结束时strDesc字符串实际上指向的不是'\0',而是它的下一个位置。

4、strlen()函数的实现

size_t MyStrLen(const char *str)
{
          assert(str != NULL); 
          size_t len = 0;
          while((*str++) != '\0')
          {
                   len++;
          }
          return len;
}

该函数实现的功能是计算字符串的长度,实现相对上面3个函数比较简单,但是使用却是很频繁的。并且strlen函数在计算长度是是不包括'\0'字符的,所以这点应该注意。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值