C/C++ strcpy() 函数实现

C/C++ strcpy() 函数实现

已知 strcpy() 函数的原型是:
char * strcpy(char * strDest,const char * strSrc);

1. 不调用库函数,实现strcpy函数。

char* myStrcpy(cahr * dest, const char * src){
	if(dest == nullptr || src == nullptr || dest == src){
		return dest;
	}
	char * temp = dest;
	while(*src != '\0'){
		*dest++ = *src++;
	}
	*dest = *src;	// 拷贝'\0'
	return temp;	// 返回原首地址
}

优化:

#include <assert.h>

char* myStrcpy(char * dest, const char * src){
	assert(dest != nullptr && src != nullptr);	// assert 断言,括号内为真时跳过,否则退出程序
	if(dest == src) return dest;
	char * temp = dest;
	while(*dest++ = *src++){	// while((*dest++ = *src++) != '\0')
		;
	}
	return temp;	// 返回原首地址
}

2. 解释为什么要返回char *

为了让 strcpy() 实现链式表达式,如 int length = strlen( strcpy( strDest, “hello world”) );

3. 考虑内存重叠的情况

对于strcpy而言,该函数并没有考虑内存重叠的问题,例如

char s[10] = "hello";
strcpy(s, s+1);    // 返回ello
// strcpy(s+1, s); // 应返回 hhello,但实际会报错,因为 dest 与 src 重叠了,把'\0'覆盖了

所谓内存重叠,就是 src 未处理的部分已经被 dest 给覆盖了,只有一种情况:
src <= dest <= src + strlen(src),即目标首地址在源地址段中间

C函数 memcpy 自带内存重叠检测功能,下面给出 memcpy 的实现 my_memcpy,当检测到内存重叠时,从高地址开始往地址遍历赋值,否则从低地址到高地址赋值。

#include <assert.h>
#include <cstring>
#include <iostream>
using namespace std;

char* mymemcpy(char* dest, const char* src, int len){   // 内存复制,因此对于字符串,长度len应包含'\0'结束符
	assert(dest != nullptr && src != nullptr);
	if(dest == src) return dest;
	char* temp = dest;
    // 当检测到内存重叠时,从高地址开始往地址遍历赋值,否则从低地址到高地址赋值
	if(dest > src && dest <= src + len - 1){
        cout << "high to low addr" << endl;
        dest = dest + len - 1;              // 最高地址开始
        src = src + len - 1;
        while(len--){
            *dest-- = *src--;
        }
    }else{
        while(len--){
            *dest++ = *src++;
        }
    }
    return temp;
}

char* myStrcpy(char * dest, const char * src){
	assert(dest != nullptr && src != nullptr);	// assert 断言,括号内为真时跳过,否则退出程序
	if(dest == src) return dest;
	char * temp = dest;

	// while(*dest++ = *src++){	// while((*dest++ = *src++) != '\0')    // 不带重叠检测,从低到高地址复制
	// 	;
	// }

    mymemcpy(dest, src, strlen(src) + 1);   // 带内存重叠检测,长度为 strlen(src) + 1

	return temp;	// 返回原首地址
}

int main(){
    char s1[10] = "hello";
    char s2[10] = "123";
    cout << myStrcpy(s1 + 2, s1) << endl;
    return 0;
}
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值