strcpy函数的实现(内含assert和const见解)

 要想自己实现strcpy函数,咱们就要先了解它功能是啥。首先我们知道它是一个复制字符串指令。

具体来说strcpy(arr2,arr1)将arr1的内容复制给arr2。ok,大致了解到这,我们先实现这一部分的内容。

实现过程是这样的:首先函数传入进去的是数组首元素地址,我用了指针接收,这个时候这个指针变量就代表了我字符串的首元素地址。接着进入循环,因为字符串“hello”,实际上是“hello\0”。我们要复制hello,那么循环条件就是找到\0为止。*arr2++ = *arr1++等价于*arr2 = *arr1;arr2++;arr1++;因为它们都是后置++,干脆把它们和在一起就变成了*arr2++ = *arr1++。这个时候就是先赋值完后一起++。最后找到\0,跳出循环,再把\0赋给arr2。

再来讲一下assert是什么,好处是什么。

assert(空间)用来代替if判断空间是否开辟成功,或者说判断是不是空指针。它和用if语句来判断空指针的好处是省事,最重要的是用assert判断出来的空指针,它会明确告诉你在哪一行犯的错误。如图:

 这里就明确告诉你在16行的assert判断出了空指针,你在顺藤摸瓜就可以知道问题出在哪了。可能你会认为这用处不大,还得自己再找。我只能说已经很好了,这才几行代码,如果做大项目的时候,一运行,发现错误,你只能慢慢找。用if语句可不会让你这么好找。

做到这里其实已经实现的差不多了。但是我们可以看到在细节上还是有点差距。

这里为了方便直接比较。可以看到原本的strcpy还有个const来修饰。

const的作用是什么呢?简单来说就是限制你的改变。

这里是const char* source,意思是不让你修改score所指向的东西大小 ,但是你可以把score所指向的东西换一个。意思就是*score(解引用了这时候代表的是地址里存储的东西,在代码中是“hello”)不能改了,但是score(存储的是地址,在代码中是arr1)能改。

既然有这个区别,当然也就有char*  const source,这个和上述的就相反。

总结一下:

    const 修饰指针
    1. const 放在*的左边, *p不能改了,也就是p指向的内容,不能通过p来改变了。但是p是可以改变的,p可以指向其他的变量
    2. const 放在*的右边,限制的是p,p不能改变,但是p指向的内容*p,是可以通过p来改变的

讲到这里,我把代码改一下顺便优化一下。 

 先前讲过实现过程,发现过程有些重复的地方。这里改了一下。

观察这个,可以发现我把*arr2++ = *arr1++直接当成判断条件。是因为原来的函数又要找到\0,又要跳出循环的时候再赋值,我直接把这个当成表达式就可以不用跳出循环的时候再赋值了。直接再循环里面赋值,然后因为\0的ASCII码值就是0,所以判断*arr2=‘\0’的时候就跳出循环,就刚刚好。

最后我们比较一下,发现还是差了一点。

 这里的strcpy是有char*类型的返回值的。有什么区别,或者是用处呢。我来展示一下。

 这里要想返回值可以直接使用出来打印,我们需要注意的是:当你while循环完之后,*arr2所指向的地址已经是最后一位数了,如果这个时候你要返回arr2的话,就无法打印出来全部的arr2,这个时候只需要把一开始的arr2所指向的字符串首元素地址存储其来,到最后返回这个值,在代码中就是ret,然后printf就按照你这个首元素地址访问整个字符串。也就是链式访问了。

这样的好处是让代码更加的灵活,如果用void的话,就无法利用这个返回值。其实很多函数都有返回值,而且都很好用,就比如scanf函数实现多组输入。

讲到这里,strcpy函数已经实现的差不多了。源码奉上:

char* my_strcpy(char* arr2, const char* arr1)
{
	assert(arr2 && arr1);
	char* ret = arr2;//把一开始的arr2所指向的字符串首元素地址存储其来
	//把src指向的字符串拷贝到dest指向是的数组空间,包括\0字符
	while (*arr2++ = *arr1++)
	{
		;
	}
	return ret;//最后返回这个值
}

int main()
{
	char arr1[] = "hello world";
	char arr2[20] = { 0 };
	//链式访问
	printf("%s\n", my_strcpy(arr2, arr1));

	return 0;
}

如果有什么地方讲错或者不理解的,欢迎指出,提问。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值