实现my_strcpy函数

题目描述:

写出完整版的strcpy函数

代码1:

char * my_strcpy(char *str1,const char *str2)   //[1]
{
    assert(str1 != NULL && str2 != NULL);    //[2]

    char *ret = str1;  //[3]

    while (*str2!='\0')//[4]
    {
    	*str1= *str2;
    	str1++;
    	str2++;
    }; 
    *(str1+1) = '\0';
    return ret;
}

分析1:

1.为什么用const修饰str2?
用const修饰原始字符串,防止原始字符串被修改。
2.为什么要有空指针检查?
不检查指针的有效性,说明答题者不注重代码的健壮性。
3.为什么返回值要返回目标地址并且返回值类型要为char*?
返回char*类型可以使函数支持链式表达式,例如:int i = strlen(strcpy(str1,str2));又如,char * str1=strcpy(new char[10],str2);返回str2的原始值是错误的。其一,源字符串肯定是已知的,返回它没有意义。其二,不能支持形如第二例的表达式。其三,把const char *作为char *返回,类型不符,编译报错。
4.如果str1,str2内存重叠,怎么办?
如果str1,str2内存发生重叠,例如strcpy(str1+1,str1),我们赋值会在赋值时将str1中的字符进行修改,并且将str1的’\0’覆盖掉,while循环就无法正常退出。所以我们还需要考虑到内存重叠的情况下怎么处理。

完整的正确代码:

char * my_strcpy(char *dst,const char *src)
{
    assert(dst != NULL && src != NULL);

    char *ret = dst;

    my_memcpy(dst, src, strlen(src)+1);

    return ret;
}

char *my_memcpy(char *dst, const char* src, int cnt)
{
    assert(dst != NULL && src != NULL);

    char *ret = dst; 

    if (dst >= src && dst <= src+cnt-1) //dst地址高于src地址并且有重复部分,从高地址开始复制
    {
        dst = dst+cnt-1;
        src = src+cnt-1;
        while (cnt--)
            *dst-- = *src--;
    }
    else    //正常情况或者dst地址低于src地址,从低地址开始复制
    {
        while (cnt--)
            *dst++ = *src++;
    }
    
    return ret;
}

主函数调用:

int main
{
	char str1[100] = "hello";
	char str2[100] = "hello,world";
	char str3[100] = "";
	char *str4 = my_strcpy(str1+1,str1);
	char *str5 = my_strcpy(str3,str2);
	cout<<"str1=>"<<str1<<endl;
	cout<<"str4=>"<<str4<<endl;
	cout<<"str5=>"<<str5;
	return 0;
}

调用结果:

在这里插入图片描述

分析2:

1.str1的内存地址高于str2的内存地址,我们就要从高地址开始赋值,这样我们才能得到我们需要的字符串
2.str1的内存地址小于str2的内存地址或者正常情况下,我们就直接从低地址开始赋值便可。
3.为什么my_strcpy函数的第二个参数为const char*类型,结果函数执行后str1的值被修改两者之间不冲突?

const char* 类型,定义一个指向字符常量的指针,这里,ptr是一个指向 char* 类型的常量,所以不能用ptr直接或者间接来修改所指向的内容,换句话说,*ptr的值为const,不能修改。但是ptr的声明并不意味着它指向的值实际上就是一个常量,而只是意味着对ptr而言,这个值是常量。实验如下:ptr指向str,而str不是const,可以直接通过str变量来修改str的值,但是确不能通过ptr指针来修改,实验如下:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值