大家好,我是苏貝,本篇博客带大家了解如何自定义实现strcpy函数,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
一. 了解strcpy函数。
函数原型:char* strcpy( char* destination , const char* source) //将source复制到destination
头文件:#include<stdio.h>
返回值:返回的是第一个目的数字的首地址,类型为char*
注意:
1.strcpy遇到 ‘\0’ 时停止,会将 ‘\0’ 复制到目的数组中,所以源数组里面要有 ‘\0’
2.目的数组的大小>=源数组,否则可能会造成缓冲溢出的错误情况
二. my_strlen
1.初阶
是不是很容易想到这种方法,当对src解引用的值不为 ‘\0’ 时,*dest = *src,然后让指针变量dest和src都指向后一位字符,直到对src解引用的值为 ‘\0’ 时,再将dest = *src= ‘\0’ ,最后返回目的数组的首元素地址
char* my_strcpy(char* dest, char* src)
{
char* ret = dest;
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
*dest = *src;
return ret;
}
int main()
{
char arr1[] = "***************";
char arr2[] = "abcdefg";
my_strcpy(arr1, arr2);
printf("%s", arr1);
return 0;
}
2.优化
将while循环里面的3条语句简化为1条语句,dest和src虽然先与++结合,但由于后置++是先使用再自增,所以在将* dest = * src后,dest和src都自增1;但是这种优化还是需要单独1条语句来将 ‘\0’ 赋值给dest,那有没有方法能在第一条*dest = *src语句时,就将 ‘\0’ 赋值给dest呢?
char* my_strcpy(char* dest, char* src)
{
char* ret = dest;
while (*src != '\0')
{
*dest++ = *src++;
}
*dest = *src;
return ret;
}
int main()
{
char arr1[] = "***************";
char arr2[] = "abcdefg";
my_strcpy(arr1, arr2);
printf("%s", arr1);
return 0;
}
3.再次优化
此次优化将*dest++ = *src++放在while后面的()中,当src解引用的值为 ‘\0’ 时,将 ‘\0’ 赋值给 *dest,表达式的值为0,退出循环。这种优化不需要单独1条语句来将 ‘\0’ 赋值给dest,但是要写出这样的代码需要自己有一定的功底
char* my_strcpy(char* dest, char* src)
{
char* ret = dest;
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[] = "***************";
char arr2[] = "abcdefg";
my_strcpy(arr1, arr2);
printf("%s", arr1);
return 0;
}
4.再次优化
写好上面的代码后,万一我们在传参时传了NULL怎么办?(用户程序是不能访问NULL的)
那么很多人大概会选择下面的这种方法吧
char* my_strcpy(char* dest, char* src)
{
if (dest != NULL && src != NULL)
{
char* ret = dest;
while (*dest++ = *src++)
{
;
}
return ret;
}
}
int main()
{
char arr1[] = "***************";
char arr2[] = "abcdefg";
my_strcpy(NULL, arr2);
printf("%s", arr1);
return 0;
}
其实还有更好的方法:使用断言
使用断言时,要引用头文件#include<assert.h>
#include<assert.h>
char* my_strcpy(char* dest, char* src)
{
assert(dest != NULL);
assert(src != NULL);
char* ret = dest;
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[] = "***************";
char arr2[] = "abcdefg";
my_strcpy(NULL, arr2);
printf("%s", arr1);
return 0;
}
当参数中有NULL时,编译器会报错,并且告诉我们错误在哪一行
5.进阶
将我们写的函数原型 char* my_strcpy(char* dest, char* src) 与strcpy的函数原型 char* strcpy( char* destination , const char* source) 对比,发现区别在char* src的前面是否有const,想了解const修饰指针变量,请点击该链接,const在* 前面,使不再有 *src被改变的风险,所以我的进阶方案是:
#include<assert.h>
#include<stdio.h>
char* my_strcpy(char* dest, const char* src)
{
assert(dest != NULL);
assert(src != NULL);
char* ret = dest;
while (*dest++ = *src++)
{
;
}
return ret;
}
int main()
{
char arr1[] = "***************";
char arr2[] = "abcdefg";
my_strcpy(NULL, arr2);
printf("%s", arr1);
return 0;
}
好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️