C++知识点——实现strlen、strcpy

1. C++函数的实现

(1)实现strlen

方法一:

int strlen(const char *StrDest){
    assert(StrDest != NULL);
	int i, i=0;
	while((*StrDest++)!='\0'){ 
		i++;
	}//从字符串第一个字符起计数,只遇到字符串结束标志'\0’停止
	return i;
}

方法二:

int strlen(const char*StrDest){
	assert(NULL != StrDest);
	return ('\0'!= *StrDest)?(1+mystrlen(StrDest+1)):0;//递归调用,无需申请全局和局部变量
}

标准库的实现:

size_t __cdecl strlen (const char * str)
{
        const char *eos = str;
        while( *eos++ ) ;
        return( eos - str - 1 );
}
(2)实现strcpy

方法一:

char * strcpy(char *dst,const char *src)  {    //[1]
    assert(dst != NULL && src != NULL);    //[2]
    char *ret = dst;  //[3]
    while ((*dst++=*src++)!='\0');    //[4]
    return ret;
}

[1]源字符串参数用const修饰,防止修改源字符串。
[2]空指针检查
(A)不检查指针的有效性,说明答题者不注重代码的健壮性。
(B)检查指针的有效性时使用assert(!dst && !src);
char *转换为bool即是类型隐式转换,这种功能虽然灵活,但更多的是导致出错概率增大和维护成本升高。
©检查指针的有效性时使用assert(dst != 0 && src != 0);
直接使用常量(如本例中的0)会减少程序的可维护性。而使用NULL代替0,如果出现拼写错误,编译器就会检查出来。
[3]返回目标地址
(A)忘记保存原始的strdst值。
[4]’\0’
(A)循环写成while (*dst++=*src++);明显是错误的。
(B)循环写成while (*src!=’\0’) *dst++=*src++;
循环体结束后,dst字符串的末尾没有正确地加上’\0’。

关于strcmp:

  1. 为什么要返回char*类型;
    为了实现链式连接。返回内容为指向目标内存的地址指针,这样可以在需要字符指针的函数中使用strcpy,例如strlen(strcpy(str1, str2))。
  2. 源地址和目标地址出现内存重叠时,如何保证复制的正确性;
    内存重叠上面的实现无法完成正常复制。c运行库中strcpy函数实现,还加入了检查内存重叠的机制:
//my_memcpy实现重叠内存转移
char* my_memcpy(char* _Dest, const char* _Source, int count){
    //检查传入参数的有效性
    assert(NULL != _Dest);
    assert(NULL != _Source);
    if (NULL ==_Dest || NULL == _Source)
         return NULL;
    char* ret = _Dest; //记录初始位置
    /**
    _Dest和_Source的内存地址有三种排列组合:
    1. _Dest和_Source没有发生重叠;
    2. _Dest的地址大于_Source的地址;
    3. _Dest的地址小于_Source的地址;
    第一种情况和第三种情况,直接从低位字节开始复制,即可;
    第二种情况,必须从高位字节开始复制,才能保证复制正确。
    */
    if (_Dest > _Source && _Dest < _Source + count - 1) {
         _Dest = _Dest + count - 1;
         _Source = _Source + count - 1;
         while(count--) {
             *_Dest-- = *_Source--;
         }
    }else{
         while(count--) {
             *_Dest++ = *_Source++;
         }
    }
    return ret;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值